【问题标题】:How does the child process not leave the while loop after the first message is read?读取第一条消息后,子进程如何不离开while循环?
【发布时间】:2017-06-01 17:31:31
【问题描述】:

我最近在尝试在 Linux C 中解决我自己的管道问题时遇到了这个示例,它确实回答了我的问题,但给了我另一个问题,为什么子进程在第一条消息之后不离开 while 循环?如果它已经将输入消息读完,那它不就在父母有机会在 sleep(5) 之后输入第二条消息之前就离开了吗?

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/ioctl.h>

    int main()
    {
        int pid = 0;

        // create pipe pair
        int fd[2];
        pipe(fd);

        pid = fork();
        if (pid == 0)
        {
            // child side
            char *buff = NULL;
            char byte = 0;
            int count = 0;

            // close write side. don't need it.
            close(fd[1]);

            // read at least one byte from the pipe.
            while (read(fd[0], &byte, 1) == 1)
            {
                if (ioctl(fd[0], FIONREAD, &count) != -1)
                {
                    fprintf(stdout,"Child: count = %d\n",count);

                    // allocate space for the byte we just read + the rest
                    //  of whatever is on the pipe.
                    buff = malloc(count+1);
                    buff[0] = byte;
                    if (read(fd[0], buff+1, count) == count)
                        fprintf(stdout,"Child: received \"%s\"\n", buff);
                    free(buff);
                }
                else
                {   // could not read in-size
                    perror("Failed to read input size.");
                }
            }

            // close our side
            close(fd[0]);
            fprintf(stdout,"Child: Shutting down.\n");
        }
        else
        {   // close read size. don't need it.
            const char msg1[] = "Message From Parent";
            const char msg2[] = "Another Message From Parent";
            close(fd[0]);
            fprintf(stdout, "Parent: sending \"%s\"\n", msg1);
            write(fd[1], msg1, sizeof(msg1));
            sleep(5); // simulate process wait
            fprintf(stdout, "Parent: sending \"%s\"\n", msg2);
            write(fd[1], msg2, sizeof(msg2));
            close(fd[1]);
            fprintf(stdout,"Parent: Shutting down.\n");
        }
        return 0;
    }

【问题讨论】:

  • 您可能需要阅读 read() 的手册页
  • read() 唯一会返回 1 以外的其他内容的时间是父级关闭管道或出现错误时。为什么循环会在那之前结束?
  • 如果家长没有发送消息,read() 将阻塞,直到有东西要读。
  • 您不应该使用ioctl(fd[0], FIONREAD, &amp;count) 来分隔消息。相反,您的协议应该具有隔离消息的内置方法(例如,通过为它们添加长度前缀或使用标记值来分隔它们)。

标签: c linux while-loop pipe


【解决方案1】:

read 阻塞直到数据到达,如果没有数据可用(除非管道被设为非阻塞)。

【讨论】:

  • 哦,好吧!那么如果父进程更新了写端,读端又会重新遍历新消息,我们可以多次这样做,直到父进程关闭管道?
  • 是的。 . . . . . .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
  • 2015-07-06
  • 2011-03-05
  • 2021-06-08
  • 1970-01-01
  • 2019-01-11
相关资源
最近更新 更多