c管道:程序在等待前停止(NULL);

c管道:程序在等待前停止(NULL);,c,pipe,C,Pipe,程序可以从管道中读取所有数据。然而,程序只是停止了。它无法继续处理。我认为它会在孩子的成长过程中停止 //I created two pipe before fork (fd[0] and fd[1]). //child process if(pid == 0){ close(fd[a][1]); buf[6]; int i; while ((i = read(fd[a][0], buf, 6)) > 0) { printf("%s", bu

程序可以从管道中读取所有数据。然而,程序只是停止了。它无法继续处理。我认为它会在孩子的成长过程中停止

//I created two pipe before fork (fd[0] and fd[1]).
//child process
if(pid == 0){
    close(fd[a][1]);
    buf[6];
    int i;
    while ((i = read(fd[a][0], buf, 6)) > 0) {
        printf("%s", buf);     
    }
    close(fd[a][0]);
exit(0); 
}

//parent process
write(fd[a][1], "12", 2);
write(fd[a][1], "14", 2);
write(fd[a][1], "15", 2);
write(fd[b][1], "12", 2);
write(fd[b][1], "14", 2);
write(fd[b][1], "15", 2);
printf("done!\n");
close(fd[0][1]);
close(fd[1][1]);
wait(NULL);
printf("Really done!!!\n");
...                      // The program cannot run after wait(NULL);

--output--
121415done

这两个进程陷入死锁,每个进程都在等待另一个进程。 您希望子进程停止处理,但它会等待父进程,因为它不知道父进程将不再发送任何数据。 要让孩子明白,请关闭管道的书写端:

write(fd[0][1], "12", 2);
write(fd[0][1], "14", 2);
write(fd[0][1], "15", 2);
printf("done!\n");
close(fd[0][1]);
wait(NULL);

这两个进程陷入死锁,每个进程都在等待另一个进程。 您希望子进程停止处理,但它会等待父进程,因为它不知道父进程将不再发送任何数据。 要让孩子明白,请关闭管道的书写端:

write(fd[0][1], "12", 2);
write(fd[0][1], "14", 2);
write(fd[0][1], "15", 2);
printf("done!\n");
close(fd[0][1]);
wait(NULL);
您在while循环中发出read,有效地阻止您自己,直到出现问题。如果需要读取6个字符,则以下是编写子进程的方式:

char buf[7];
int left = 6;
int so_far = 0;   // instead of so_far, (6 - left) could also be used
while (left > 0)
     int num_read = read(fd[0][0], buf + so_far, left);
     left -= num_read;
     so_far += num_read;
}
buf[so_far] = '\0';
printf("%s\n", buf);     
您在while循环中发出read,有效地阻止您自己,直到出现问题。如果需要读取6个字符,则以下是编写子进程的方式:

char buf[7];
int left = 6;
int so_far = 0;   // instead of so_far, (6 - left) could also be used
while (left > 0)
     int num_read = read(fd[0][0], buf + so_far, left);
     left -= num_read;
     so_far += num_read;
}
buf[so_far] = '\0';
printf("%s\n", buf);     

我怀疑您没有在子进程中关闭write fd,因此对read的调用将被阻塞,这反过来又会阻塞父进程中的wait


另外:如果你在回答@anatolyg的问题时遗漏了什么,你应该编辑这个问题。这与我一开始给出的答案相同。

我怀疑您没有在子进程中关闭write fd,因此对read的调用将被阻塞,而这又会阻塞父进程中的wait



另外:如果你在回答@anatolyg的问题时遗漏了什么,你应该编辑这个问题。这和我一开始给出的答案是一样的。

你能举一个完整的例子吗?请看@Joachim Pileborg,我已经提供了我的程序的更多细节。你能举一个完整的例子吗?请参阅@Joachim Pileborg我已经提供了我的程序的更多细节。它已经包含在我的代码中[0][1]。然而,我没有展示出来。抱歉…..我的代码中已包含[0][1]。然而,我没有展示出来。对不起……谢谢你的帮助。我编辑了我的代码。该问题可以在waitNULL;之后继续处理;。然而,它得到了想要的输出,就像下面的子级只得到第一次写入一样。它得到了错误的数据。2021年完成!真的完成了!!!非常感谢你。我解决了这个问题。你的代码是完美的。实际上,上次我犯了一些愚蠢的错误,程序无法运行。我还有一个小问题。我怎样才能在buf中画一条折线?你是说一个“\n”?只要你想在哪里:buf[到目前为止]='\n';然后到目前为止,但不是左。这是因为您正在生成数据,所以到目前为止仍在继续,但您仍然希望剩余的数据量相同。如果您计划将缓冲区用作字符串(例如打印时使用%s),请不要忘记在缓冲区中为结尾“\0”加一个字符。谢谢您的帮助。我编辑了我的代码。该问题可以在waitNULL;之后继续处理;。然而,它得到了想要的输出,就像下面的子级只得到第一次写入一样。它得到了错误的数据。2021年完成!真的完成了!!!非常感谢你。我解决了这个问题。你的代码是完美的。实际上,上次我犯了一些愚蠢的错误,程序无法运行。我还有一个小问题。我怎样才能在buf中画一条折线?你是说一个“\n”?只要你想在哪里:buf[到目前为止]='\n';然后到目前为止,但不是左。这是因为您正在生成数据,所以到目前为止仍在继续,但您仍然希望剩余的数据量相同。如果您计划将缓冲区用作字符串(例如打印时使用%s),请不要忘记在缓冲区中为结尾“\0”加一个字符。谢谢您的建议。我已经在子进程中添加了close fd。但是,问题仍然没有解决。@EricTang-在开始阅读之前,您需要在子进程中关闭fd[1]或[a][1]-写入文件描述符。哦,抱歉,我错过了它。但问题仍然存在。谢谢你的建议。我已经在子进程中添加了close fd。但是,问题仍然没有解决。@EricTang-在开始阅读之前,您需要在子进程中关闭fd[1]或[a][1]-写入文件描述符。哦,抱歉,我错过了它。但问题仍然存在。