初学管道实现时的阻塞问题~
[code]
#include <unistd.h>
#include <sys/types.h>
main(){
int pipe_fd[2];
pid_t pid;
char r_buf[4];
char* w_buf;
int writenum;
int cmd;
memset(r_buf,0,sizeof(r_buf));
if(pipe(pipe_fd) <0)
{
printf( "pipe create error\n ");
return -1;
}
if((pid=fork())==0)
{
close(pipe_fd[0]);
close(pipe_fd[1]); //注意这两行
sleep(10);
exit();
}
else if(pid> 0)
{
sleep(1);
close(pipe_fd[0]);
write w_buf= "111 ";
if((writenum=write(pipe_fd[1],w_buf,4))==-1)
printf( "write to pipe error\n ");
else
printf( "the bytes write to pipe is %d \n ", writenum);
close(pipe_fd[1]);
}
}
//上面将发生 Broken Pipe
#include <unistd.h>
#include <sys/types.h>
main(){
int pipe_fd[2];
pid_t pid;
char r_buf[4];
char* w_buf;
int writenum;
int cmd;
memset(r_buf,0,sizeof(r_buf));
if(pipe(pipe_fd) <0)
{
printf( "pipe create error\n ");
return -1;
}
if((pid=fork())==0)
{
close(pipe_fd[1]);
read(pipe_fd[0],r_buf,sizeof(r_buf);//加入了这行 就不会Broken Pipe 了 小弟不解 望高手解释下这里所做的~~ 为什么多了这句就能开放管道的读端了呢?
close(pipe_fd[0]); //注意这两行
sleep(10);
exit();
}
else if(pid> 0)
{
sleep(1);
close(pipe_fd[0]);
write w_buf= "111 ";
if((writenum=write(pipe_fd[1],w_buf,4))==-1)
printf( "write to pipe error\n ");
else
printf( "the bytes write to pipe is %d \n ", writenum);
close(pipe_fd[1]);
}
}
------解决方案--------------------你要记得fork之后父子的pipe_fd[0]或pipe_fd[1]必须都关闭才能真正关闭0或1
原因是二种情况下,子调用read函数阻塞,因为这时没有数据可读。父进程sleep(1)后向管道中写了4字节,然后关闭管道写描述符,然后子的read返回,关闭读,再睡10秒后退出。这时没有发生:向读端已关闭的pipe写的情况。
第一种情况下,子先关闭
close(pipe_fd[0]);
close(pipe_fd[1]);
sleep(10); //关闭管道两端后,sleep(10),
在子开始sleep的时候,父的sleep(1)才完成,然后close(pipe_fd[0]);至此pipe的读端真正被关闭了,然后的write就是一个写对端关闭的错误操作。