进程间通信——管道

http://blog.csdn.net/lne818/article/details/1005052

管道不支持文件定位操作

管道  

  • 父子进程或兄弟进程间的通信
  • 数据只能单向流动,要求双向通信时需建立两条管道
  • 通过建立于内存中的文件实现

管道的使用

  • int fd[2];  int pipe(fd);     (#include <unistd.h>)  相当于同时open两个文件描述符
  • 其中 fd[0] 用于读   fd[1]用于写,通过缓存PIPE_BUF连接
  • PIPE_BUF满时,写端阻塞;PIPE_BUF空时,读段返回0
  • 写端关闭后,写入的数据仍存在,直到读出为止
  • 读端关闭后(各亲缘进程中读端均关闭),写入的数据会使本进程收到内核传来的SIGPIPE信号,默认终止进程
  • linux不保证写操作的原子性,一次write操作可能被分多次写入PIPE_BUF

有名管道  

  • 对管道的改进,无名管道通信用的文件描述符必须通过进程的亲缘关系传递。
  • 有名管道使得通信用的文件描述符可通过管道名获得,故支持任意进程间的通信
有名管道的使用

  • int mkfifo(const char * pathname, mode_t mode)      (#include <sys/types.h>  #include <sys/stat.h>)
  • pathname为文件系统中存在的文件时,返回ENXIO错误
  • 如果有进程写打开FIFO,且当前FIFO内没有数据,则对于设置了阻塞标志的读操作来说,将一直阻塞。对于没有设置阻塞标志读操作来说则返回-1,当前errno值为EAGAIN,提醒以后再试。
  • 对于设置了阻塞标志的读操作说,造成阻塞的原因有两种:当前FIFO内有数据,但有其它进程在读这些数据;另外就是FIFO内没有数据。解阻塞的原因则是FIFO中有新的数据写入,不论信写入数据量的大小,也不论读操作请求多少数据量。
  • 读打开的阻塞标志只对本进程第一个读操作施加作用,如果本进程内有多个读操作序列,则在第一个读操作被唤醒并完成读操作后,其它将要执行的读操作将不再阻塞,即使在执行读操作时,FIFO中没有数据也一样(此时,读操作返回0)。
  • 如果没有进程写打开FIFO,则设置了阻塞标志的读操作会阻塞。

  • 对于设置了阻塞标志的写操作:

当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区中能够容纳要写入的字节数时,才开始进行一次性写操作。
当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。FIFO缓冲区一有空闲区域,写进程就会试图向管道写入数据,写操作在写完所有请求写的数据后返回。
  • 对于没有设置阻塞标志的写操作:
当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。在写满所有FIFO空闲缓冲区后,写操作返回。
当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果当前FIFO空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;如果当前FIFO空闲缓冲区不能够容纳请求写入的字节数,则返回EAGAIN错误,提醒以后再写;












        • 0
          点赞
        • 0
          收藏
          觉得还不错? 一键收藏
        • 0
          评论

        “相关推荐”对你有帮助么?

        • 非常没帮助
        • 没帮助
        • 一般
        • 有帮助
        • 非常有帮助
        提交
        评论
        添加红包

        请填写红包祝福语或标题

        红包个数最小为10个

        红包金额最低5元

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

        抵扣说明:

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

        余额充值