IPC之管道

  

现在linux使用的IPC(进程间通信,进程间通信)方式有以下几种:
- - - - - -(1)管道(管)和匿名管道(FIFO)
- - - - - -(2)信号(信号)
-(3)消息队列
- - - - - -(4)共享内存
- - - - - -(5)信号量
- - - - - -(6)套接字(socket)

  

什么是管道

  

管道是Unix中最古老的进程间通信的形式。我们把一个进程连接到另一个进程的一个数据流成为一个“管道”。

  
      <李>管道是<强>半双工强的,数据只能向一个方向流动,需要双方通信的时候,需要建立其两个管道。   <李>   

    只能用于父子进程或者兄弟进程之间(<强>具有亲缘关系强劲的进程)进行通信。

      

    管函数

      
     <代码类=" c语言"> # include & lt; unistd.h>
      int管(int pipefd[2]);  
      

    功能:创建无名管道
    参数:文件描述符组.fd[0]表示读端,fd[1]表示写端。
    返回值:成功返回0,失败返回错误代码

    也就是说,在fork()之前管(),就可以使得父子进程之间建立起一个管道,画个图:
     IPC之管道“> <br/>父子进程都会打开5个文件描述符,除了默认的0,1,2,还有fd [0], fd[1]。测试一下,就会知道这两个文件描述符为3,4。<br/>写串代码用一用:</p>
  <pre> <代码类= # include & lt; stdio.h>   # include & lt; stdlib.h>   # include & lt; string.h>   # include & lt; unistd.h>      int main ()   {   int fd [2];   int retByte;   pid_t pid;   char buf [20]=" ";      管(fd);/*创建无名管道*///printf (" % d % d \ n”, fd [0], fd [1]);      pid=fork ();   如果(pid==1)   {   perror(“创建叉”);   返回1;   }   如果(pid==0)   {//子进程,写端,使用fd [1]//关闭(fd [0]);//关闭(fd [1]);   而(1)   {   scanf (“% s”, buf);   如果(写(fd[1],但,strlen (buf))==1)   {   perror(“写”);   返回1;   }   memset (buf 0 20);   如果(读(fd [0] buf 5)比;0 )   {   printf("孩子读味精:% s \ n”, buf);   }   }   }   其他的   {//父进程,读端,使用fd [0]   而(1)   {   memset (buf 0 20);   retByte=阅读(fd [0] buf 5);//每次只读5个   如果(retByte==1)   {   perror(“读”);   返回1;   }   如果(retByte比;0)   {   printf (" parent-read味精:% s \ n ", buf);   }   }   }   返回0;   }   

    运行结果:
     IPC之管道“> <br/>那么,如果没有读端呢?也就是父子进程的fd[0]都关闭了,会有什么现象呢? </p>
  <pre> <代码>空白处理程序(int)
  {
  printf (   

    运行结果:
     IPC之管道“> <br/>会出现管道破裂! !(如果没有重写管道破裂的处理函数,系统默认的处理方式就是杀死进程,父子进程都超过了)</p>
  <h3>管道读写规则</h3>
  <p>所以,总结一下读写规则:<br/>读规则:<br/> 1)缓冲区没数据:阻塞<br/> 2)缓冲区的数据少于请求字节数:缓冲区有多少就读多少<br/> 3)缓冲区的数据多于请求字节数:只读取请求字节数,剩下的还在缓冲区<br/> 4)写端关闭:读端等待。<br/>写规则:<br/> 1)缓冲区满了:写不进去<br/> 2)没有读端:管道破裂,父子进程都结束了。调试到写,发生SIGPIPE。<br/>注意:读端和写端的对应关系可以是一对一,一对多、多对一、多对多的。</p>
  <h3>练习</h3>
  <p>上面讲到,缓冲区如果满了,就写不进去了。那么缓冲区有多大呢?换言之,如何检测linux中管道的容量? <h2 class=IPC之管道