Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 读取第一条消息后,子进程如何不离开while循环?_C_Linux_While Loop_Pipe - Fatal编程技术网

C 读取第一条消息后,子进程如何不离开while循环?

C 读取第一条消息后,子进程如何不离开while循环?,c,linux,while-loop,pipe,C,Linux,While Loop,Pipe,我最近在Linux C中尝试解决我自己的管道问题时遇到了这个例子,它确实回答了我的问题,但给了我另一个问题,为什么子进程在第一条消息之后不留下while循环?如果它已经将输入消息读到了最后,它会不会在父母有机会在睡眠后输入第二条消息之前离开(5) #包括 #包括 #包括 int main() { int-pid=0; //创建管道对 int-fd[2]; 管道(fd); pid=fork(); 如果(pid==0) { //儿童方面 char*buff=NULL; 字符字节=0; 整数计数=0;

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

#包括
#包括
#包括
int main()
{
int-pid=0;
//创建管道对
int-fd[2];
管道(fd);
pid=fork();
如果(pid==0)
{
//儿童方面
char*buff=NULL;
字符字节=0;
整数计数=0;
//关闭写端。不需要它。
关闭(fd[1]);
//从管道中读取至少一个字节。
while(读取(fd[0],&字节,1)==1)
{
if(ioctl(fd[0]、FIONREAD和count)!=-1)
{
fprintf(标准输出,“子:计数=%d\n”,计数);
//为我们刚刚读取的字节+其余字节分配空间
//不管管里有什么。
buff=malloc(计数+1);
buff[0]=字节;
如果(读取(fd[0],buff+1,计数)=计数)
fprintf(标准输出,“子:接收\%s\”\n”,buff);
免费(buff);
}
其他的
{//无法读取大小
perror(“读取输入大小失败”);
}
}
//靠拢
关闭(fd[0]);
fprintf(标准输出,“子级:正在关闭。\n”);
}
其他的
{//关闭读取大小。不需要它。
const char msg1[]=“来自父级的消息”;
const char msg2[]=“来自父级的另一条消息”;
关闭(fd[0]);
fprintf(标准输出,“父级:发送\%s\”\n”,msg1);
写入(fd[1],msg1,sizeof(msg1));
sleep(5);//模拟进程等待
fprintf(标准输出,“父级:发送\%s\”\n”,msg2);
写入(fd[1],msg2,sizeof(msg2));
关闭(fd[1]);
fprintf(标准输出,“父级:正在关闭。\n”);
}
返回0;
}

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

您可能需要读取
read()
的手册页
read()
唯一返回
1
以外的内容的时间是父管道关闭或出现错误时。为什么循环会在此之前结束?如果父级尚未发送消息,
read()
将一直阻止,直到有东西要读取。您不应该使用
ioctl(fd[0],FIONREAD,&count)
来分隔消息。相反,您的协议应该有一个内置的隔离消息的方法(例如,通过长度前缀或使用哨兵值来分隔消息)。哦,好的!因此,如果父进程更新了写入端,则读取端会再次检查新消息,我们可以多次这样做,直到父进程关闭管道?是的。
    #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;
    }