Я написал простую пару программ чтения-записи. Writer создает/открывает FIFO-файл и постоянно записывает в него строку. Читатель просто читает его и записывает в стандартный вывод. Читатель делает это только 10 раз, а затем выходит. Удивительно (для меня), что писатель почти сразу же уходит. Он не просто выходит из цикла записи, он как бы выпрыгивает из него, я могу сказать это, не видя финального «до свидания» на экране. Я мог бы принять такое поведение, но я до сих пор не могу понять, почему. Может ли кто-нибудь поделиться со мной своими знаниями?
/* writer code */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
char msg [] = "Leo_Tolstoy";
size_t len = strlen("Leo_Tolstoy");
if (mkfifo ("myfifo", 0600) != 0) {
perror ("creating fifo");
}
int fd;
if ( (fd = open ("myfifo", O_WRONLY)) == -1) {
perror ("opening fifo");
exit (1);
}
while (1)
{
int r = write (fd, msg, len);
if (r == -1)
perror ("writing");
sleep(1);
}
printf ("byebye\n");
close (fd);
return 0;
}
/* reader code */
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/shm.h>
int main()
{
char buf[50];
printf ("bef opening\n");
int fd = open ("myfifo", O_RDONLY);
if (fd == -1) {
perror ("opening fifo");
exit (1);
}
printf ("bef reading\n");
int cnt=0;
while (cnt < 10)
{
int r = read (fd, buf, 50);
if (r == 0)
break;
if (r == -1)
perror ("reading");
write (1, buf, r);
cnt++;
}
// close (fd);
return 0;
}
if (mkfifo ("myfifo", 0600) != 0)
использует восьмеричное значение, 384 десятичное, если это уместно. - person Weather Vane   schedule 23.08.2016man 2 umask
. должны сообщить вам об актуальности этого значения. - person WhozCraig   schedule 23.08.20160600
это разрешения для узла FIFO. там написаноoctal
,owner=read/write
,group=no permissions
,world=no permissions
- person user3629249   schedule 25.08.2016int r = write (fd, msg, len);
не совсем корректна. функция:write()
возвращаетssize_t
, а неint
- person user3629249   schedule 25.08.2016mkfifo()
терпит неудачу, нет причин продолжать выполнение кода после вывода сообщения об ошибке, поэтому за вызовомperror()
должен следовать вызовexit( EXIT_FAILURE );
- person user3629249   schedule 25.08.2016mkfifo()
завершится ошибкой с кодом ошибкиEEXIST
, когда fifo уже существует. Настоятельно рекомендуем 1) проверить наличие ошибок 2) удалить файл fifo после завершения связи - person user3629249   schedule 25.08.2016#include <unistd.h>
, поэтому функции:read()
иwrite()
не определены - person user3629249   schedule 25.08.2016if (r == -1)
, затем следует все вызовыperror()
, для этого требуется следующий оператор:exit( EXIT_FAILURE );
- person user3629249   schedule 25.08.2016close(fd);
, когда закончит чтение fifo - person user3629249   schedule 25.08.2016r
НЕ является осмысленным именем переменной. 2) отдельные блоки кода (for, if, else, while, do...while, switch, case, default) через пустую строку - person user3629249   schedule 25.08.2016gcc
при минимальном использовании:-Wall -Wextra -pedantic
также использую:-Wconversion -std=gnu99
) - person user3629249   schedule 25.08.2016enum
или оператор#define
, чтобы дать этим «магическим» числам осмысленные имена, а затем использовать эти осмысленные имена во всем коде. - person user3629249   schedule 25.08.2016main()
не имеет оператора return 0;` в конце, компилятор автоматически вызовет возврат 0, поэтому больше нет необходимости иметь операторreturn 0;
в конце - person user3629249   schedule 25.08.2016