使用管道需要注意的四种特殊情况

第一种情况:

如果所有指向管道写端的文件描述符都关闭后,还有进程在读的话,当管道所有内容读完后,再次read会返回0.

wKioL1cM5mnAtwNjAABTQWSTGiU181.png

 

运行结果:

 wKiom1cM5faRCWO6AAAYXNmFwtg885.png

结果分析:我们在子进程里面写了10次,写完后关闭写,然后父进程读,读了10次之后当读第11次时候,read返回了0,证明管道空了,所以输出了 “pipe is empty,chile quit.

第二种情况:

     如果有指向管道写端的文件描述符都没关闭,而持有写端的进程也没向管道写数据,当有进程从管道读数据的话,那么当管道中所有数据都被读完后,再次read阻塞,知道管道中再次有了数据才读取数据并返回。

 wKioL1cM5vSTrPJjAABQj2l-pZY071.png

运行结果:

 wKiom1cM5lmBsqhSAAAa49abSD8316.png

  从结果可以看到,当count值为10,9,8,7,6,5的时候,子进程没有写,所以父进程这几次都在阻塞,知道当count小于5时,父进程才开始读了,只向终端输出了4次(4,3,2,1时),

这里体现了阻塞。

 

第三种情况:

   如果所有指向管道写端的文件描述符都关闭了,当有进程向管道的写端write时,那么该进程会收到SIGPIPE信号,通常会导致进程异常终止。

 wKiom1cM5piywzCKAABUoCPohqo334.png

运行结果:

 wKioL1cM52HB8SpTAAAVv3MnaiI521.png

 

结果分析:

子进程关闭读端,然后向管道写了10次(count次)后,关闭写端,而父进程则先关闭写端,读了5次之后,关闭了读端,然后收到子进程的退出码,我们在这里会看到退出码是13,可见子进程是异常终止的。

第四种情况:

如果有管道读端的文件描述符没有关闭,而持有管道读端的进程也没有向管道中读数据,这时有进程向管道写端写数据,那么在管道写满时再次write会阻塞,直到管道中有了空位置才写入数据并返回。

 wKioL1cM56HSddNpAAA_XpwMaQA207.png

结果:

 wKioL1cM582RhdDwAABywVpOAsM064.png

 

   我们先让子进程一直写,(死循还),父进程sleep(5),我们会看到当管道写满时,就会阻塞,5秒之后父进程读取了数据,然后子进程又开始写了。