FIFO文件关闭时读取器进程终止

时间:2016-08-23 18:44:55

标签: c glibc mkfifo

我写了一对简单的读写器程序。 Writer创建/打开一个FIFO文件,并不断在其中写入一个字符串。读者只是阅读它并写入stdout。读者只会这样做10次然后退出。令人惊讶的是(对我来说)作家几乎立即退出。它不仅仅是写出循环,它似乎从它跳出来,我可以告诉它没有在屏幕上看到最后的“byebye”。我可以接受这种行为,但我仍然无法理解为什么。 有人可以和我分享他们的知识吗?

/* 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;
}

1 个答案:

答案 0 :(得分:2)

当退出时(10次迭代之后),由于读取结束被关闭,作者会收到SIGPIPE。因此,执行信号SIGPIPE的默认操作以终止程序。这就是为什么你没有看到最终的printf()没有被执行。

相反,您可以通过调用SIG_IGN忽略(SIGPIPE)编写器中的信号sigaction(),然后自己处理写入错误。