我想了解管道。我有这个小程序,它使用管道从父进程向其子进程发送消息。孩子接收了所有3条消息,但在阅读完最后一条消息后,它不会退出。我究竟做错了什么?感谢。
PS:我注意到,如果我在父母的while循环中睡2秒钟,那就可以了。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main(){
int desc[2];
pipe(desc);
int pid = fork();
if(pid == 0){
while(1){
sleep(1);
char buffer[16];
if(read(desc[0], buffer, 16) != 16){
printf("Error or finished");
exit(0);
};
printf("Child: message recieved - '%s'\n", buffer);
}
close(desc[1]);
}
if(pid > 0){
int i=0;
while(i <= 2){
char buffer[100];
i++; char x[10];
strcpy(buffer, "Hello, child!");
sprintf(x, " %d", i);
strcat(buffer, x);
if(write(desc[1], buffer, 16) != 16){
printf("Error");
exit(0);
};
}
close(desc[0]);
}
return 0;
}
答案 0 :(得分:3)
您必须正确关闭管道末端。读取器将挂起,直到管道的所有写入端都关闭。
if(pid == 0){
close(desc[1]); // close write end in reader
while(1){
...
read(desc[0], buffer, 16);
...
}
}
if(pid > 0){
int i=0;
close(desc[0]); // close read end in writer; not required, but makes code cleaner
while(i <= 2){
...
write(desc[1], buffer, 16);
...
}
close(desc[1]); // close write end in writer
}
答案 1 :(得分:3)
您忘记关闭父母和孩子中管道的无用端。实际上你的孩子拥有阅读和写入管道的一部分,因此他无法检测文件的结尾,因为存在一个编写器(本身!),所以它在读取时被阻止。将您的代码更改为:
if(pid == 0){
close(desc[1]); // Child is not a writer, so close the write part immediately!
while(1){
...
}
}
if(pid > 0){
close(desc[0]); // Parent is not a reader, so close the read part immediately!
int i=0;
while(i <= 2){
...
}
}
请记住,在管道上,文件结尾是&#34;在管道中没有其他内容可以读取#34; 和&#34;没有更多的作家&#34;。