进程间通信1

管道

  管道由于传递数据只能单向传递,因此又称半双工管道,它是一种两个进程间进行单向通信的机制.
  局限性
   *数据只能由一个进程流向另一个进程,若要进行全双工通信,则需建立两个管道.
   *管道只能用于具有亲缘关系的进程间通信.
   *管道无名字.
   *管道的缓冲区大小受限制.
   *管道所传递的是无格式的字节流,这就要求管道的输入和输出事先约定好数据格式.

  使用管道进行通信时,两端的进程向管道读写数据是通过创建管道时,系统设置的文件描述符进行的.
  管道是一个特殊的文件,这个文件只存在于内存中.在创建管道时,系统为管道分配一个页面作为数据缓冲区,进行管道通信的两个进程通过读写这个缓冲区来进行通信.
  写入的数据每次添加在管道缓冲区的末尾,读数据时都是从缓冲区的头部读出数据.

管道的创建

 linux下创建管道可以通过函数pipe完成,该函数如果调用成功返回0,并且数组中将包含两个新的文件描述符.如果有错误发生,则返回-1.
 
 这里写图片描述
 
 管道两端分别用描述符fd[0]及fd[1]来描述.
 管道两端的任务固定.fd[0]为管道读端,fd[1]为管道写端.
 管道是一种文件,创建成功后就可以作为一般文件来使用,因此对文件操作的I/O函数都可以用于管道,如read(),write()等.
 
 管道的一般用法
 进程在使用fork函数创建子进程前先创建一个管道,该管道用于在父子进程间通信.然后创建子进程,之后父进程关闭管道读端,子进程关闭管道写端,父进程负责向管道写数据,子进程负责读数据.也可以父进程关闭管道写端,子进程关闭管道读端.

管道的读写

从管道中读数据

  要读取管道中数据的进程要关闭管道写端fd1,同时向管道写数据的进程应关闭读端fd0.(因为是用于具有亲缘关系的进程间通信,所以共享文件描述符).使用前,应及时关闭不需要的另一端,避免错误的发生.
  
进程在管道的读端读数据时
   1.如果管道写端不存在,则读进程认为已经读到数据的末尾,读函数返回读出的字节数为.
   2.若管道写端存在,
   (1)且请求读取的字节数大于PIPE_BUF,则返回管道中所有数据,
   (2)如果不大于PIPE_BUF,则返回管道中现有的所有数据(管道中数据量小于请求的数据量). 或返回请求的字节数(管道中数据量大于等于请求的数据量)

向管道中写数据

 如果某进程希望向管道中写入数据,那么该进程应关闭读端fd0文件描述符,同时管道另一端的进程关闭fd1.
 向管道写入数据时,linux不保证写入的原子性.
 >原子性:操作在任何时候都不能被任何原因打断,操作要么不做要么就一定完成.
 管道缓冲区一有空闲区域,写进程就会试图向管道写入数据,若读进程不读走缓冲区的数据,则写操作一直被阻塞等待.
  
  在写管道时,如果请求的字节数小于等于PIPE_BUF,则多个进程对同一管道的写操作不会交错进行,但如果有多个进程同时写一个管道,且某些进程要求写的字节数超过PIPE_BUF所能容纳时,则多个写操作的数据可能会交错.

  >只由管道读端存在时,向管道中写入数据才有意义.否则,向管道中写入数据的进程将收到内核传来的SIGPIPE信号,如果忽略或扑捉该信号并从其处理程序返回,则write出错,错误码为EPIPE.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值