关于C#:UNIX FIFO:如果我不关闭fifo的输入端,进程将挂起

UNIX FIFO: the process hangs if I don't close the input side of the fifo

我刚开始使用UNIX FIFO,在尝试第一个FIFO程序时发现了一些东西。 该程序以这种方式工作:创建FIFO后,使用fork()函数启动两个进程。 子进程读取父亲通过FIFO传递给他的内容,并将其打印在屏幕上。 交换的数据是指定为参数的字符串。 问题是:在父亲部分,如果我忘记关闭FIFO的输入端(这意味着我排除了close(fd)行),则即使进程之间的数据正确交换,程序也只会挂起。 否则,一切正常,程序将终止且不会挂起。 有人可以解释一下为什么吗?

谢谢你的耐心。 这是主要功能的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        printf("An argument must be specified\
"
);
        return -1;
    }  

    int ret = mkfifo("./fifo.txt", 0644);
    char buf;

    if(ret < 0)
    {
        perror("Error creating FIFO");
        return -1;
    }

    pid_t pid = fork();

    if(pid < 0)
    {
        perror("Error creating child process");
        return -1;
    }

    if(pid == 0) /* child */
    {
        int fd = open("./fifo.txt", O_RDONLY); /* opens the fifo in reading mode */

        while(read(fd, &buf, 1) > 0)
        {
            write(STDOUT_FILENO, &buf, 1);
        }
        write(STDOUT_FILENO,"\
"
, 1);
        close(fd);
        return 0;
    }
    else /* father */
    {
        int fd = open("./fifo.txt", O_WRONLY); /* opens the fifo in writing mode */

        write(fd, argv[1], strlen(argv[1]));
        close(fd);
        waitpid(pid, NULL, 0);
        return 0;
    }
}


read(2)阻塞,直到有可用字符或通道的另一端关闭为止。父进程必须关闭管道,以使最后一个子read()返回。如果在父亲中省略close(fd),则孩子将阻塞read(),直到父亲退出(自动关闭管道),但父亲将挂在waitpid()中,直到孩子退出。


首先,第一件事:您发布的代码存在多个问题。

  • 没有#include指令,因此在您调用的任何函数的范围内都没有原型。 C89需要可变参数功能的原型,例如printf(); C99需要所有功能的原型。 C89和C99都需要在O_RDONLYO_WRONLYSTDOUT_FILENONULL范围内声明。
  • -1不是main()的允许返回值。
  • C89不允许混合声明和语句。
  • 未成年人:通常的称呼是"父母和孩子",而不是"父亲和孩子"。

    我已修改您的程序以纠正此问题并提高可读性:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/wait.h>

    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>

    int
    main(int argc, char *argv[])
    {
        if (argc != 2) {
            printf("An argument must be specified\
    "
    );
            return 1;
        }

        int ret = mkfifo("./fifo.txt", 0644);
        char buf;

        if (ret < 0) {
            perror("Error creating FIFO");
            return 1;
        }

        pid_t pid = fork();

        if (pid < 0) {
            perror("Error creating child process");
            return 1;
        }

        if (pid == 0) { /* child */
            int fd = open("./fifo.txt", O_RDONLY); /* opens the fifo in reading mode */

            while(read(fd, &buf, 1) > 0) {
                write(STDOUT_FILENO, &buf, 1);
            }
            write(STDOUT_FILENO,"\
    "
    , 1);
            close(fd);
            return 0;
        } else { /* parent */
            int fd = open("./fifo.txt", O_WRONLY); /* opens the fifo in writing mode */

            write(fd, argv[1], strlen(argv[1]));
            close(fd);
            waitpid(pid, NULL, 0);
            return 0;
        }
    }

    但最重要的是,您没有提到要使用的操作系统和编译器。

    我无法重现该问题,并且我怀疑它可能与上面列出的问题之一有关。