管道通信
在学习进程间通信的管道通信的时候,遇到一个问题,特地拿出来让各位帮忙看看。下面程序完成了命令行下的“who|wc -l”功能,创建了两个子进程:一个实现“who”,向管道中写数据,一个实现“wc -l”,从管道中读数据。代码如下:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int pfd[2];
pid_t pid1,pid2;
pipe(pfd); //创建管道
switch(pid1=fork()) {
case -1:
printf("-1");exit(1);
case 0: // 完成往管道中写数据的子进程
dup2(pfd[1],STDOUT_FILENO);
close(pfd[0]);
close(pfd[1]); //(1):把这一行注释掉
execlp("who","who",(char*)NULL);
exit(1);
}
switch(pid2=fork()) {
case -1:
printf("-1");exit(1);
case 0: //完成从管道中读数据的子进程
dup2(pfd[0],STDIN_FILENO);
close(pfd[0]);
close(pfd[1]); //(3)
execlp("wc","wc","-l",(char*)NULL);
exit(1);
}
close(pfd[0]);
close(pfd[1]); //(2):把这一行注释掉
waitpid(pid1,NULL,0); //等待子进程结束
waitpid(pid2,NULL,0);
return 0;
}
上面程序中,如果在(2)处,把代码注释掉,即不关闭管道的写文件描述符,那么程序会被挂起。原因是,在子进程2(wc)中只有获得文件结尾后,才会停止读数据,但存在对管道打开的写文件描述符没有关闭,所以"wc"没有获得文件结尾,所以并不会终止,因而挂起。当然,在(3)处注释掉,程序也必然挂起。
但是,如果把(1)处注释掉,即在进程(1)中不关闭管道的写文件描述符,那么程序不会挂起。我想不明白的是,子进程(1)(2)都是由父进程创建的,传递的文件描述符应该指向同一个地方,为什么子进程(1)的写文件描述符关闭与否,子进程(2)不知道?
待解决中。。。