进程间通信方式之管道--有名管道

接上一篇的无名管道,今天总结一下进程间通信的有名管道。

有名管道可以克服无名管道的一个限制,即因为没有具体的名字,它只能用于具有亲缘关系的进程间的通信。原因是有名管道提供了一个路径名与之关联,并以FIFO的文件形式存在于文件系统中。于是,即使与FIFO的创建进程不存在亲缘关系的进程,只要有可以访问该路径,FIFO就可以为它们提供通信,所以有名管道不仅可以用于有亲缘关系间的通信,也可以用于无亲缘进程之间的通信。

FIFO严格遵循先进先出的原则,对管道以及FIFO的读取总是从开始处返回数据的,对它们进行写操作时,则把数据添加到末尾处,并且它不支持lseek()函数等文件定位操作。

mkfifo()

功能:创建有名管道

头文件:#include <sys/types.h>

#include <sys/stat.h>

原型:int mkfifo(char *pathname,mode_t mode)

说明:创建的文件必须在创建前不存在;

      mode是该文件的权限

返回值:成功,返回0;失败,返回-1.

从FIFO中读取数据:

约定:如果一个进程为了从FIFO中读取数据而打开FIFO,那么称该进程内的读操作为设置了阻塞标志的读操作。

1、如果FIFO中有数据,则设置了阻塞标志的读操作不会因为FIFO中的字节数小于请求读的字节数而堵塞,只会返回现在FIFO中实际有的数据量;

2、如果有进程写打开FIFO,且当前FIFO内没有数据,则对于设置了阻塞标志的读操作来说,将一直处于阻塞。对于没有设置阻塞标志的读操作来说则会返回-1,当前errno值为EAGAIN,提醒再试;

3、对于设置了阻塞标志的读操作来说,造成阻塞有两种原因:当前FIFO内有数据,但有其他进程在读这些数据;另外就是FIFO内没有数据。不阻塞的原因则是FIFO中国有新的数据写入,不论写入的数据量的大小,也不论读操作请求多少数据量;

4、读打开的阻塞标志只对本进程第一个读操作起作用,如果本进程内有多个读操作序列,则在第一个读操作被唤醒并完成读操作后,其他将要执行的读操作将不再阻塞,即使在执行读操作时,FIFO中没有数据也一样,读操作返回0;

5、如果没有进程写打开FIFO,则设置了阻塞标志的读操作会阻塞。

向FIFO中写入数据:

约定:如果一个进程为了向FIFO中写入数据而阻塞打开FIFO,那么称该进程内的写操作为设置了阻塞标志的写操作。

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

   (1)当要写入的数据量不大于PIPE_BUF时,Linux将保证其写入的原子性。如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区能够容纳要写入的字节数时,才开始进行一次性写操作;

   (2)当要写入的数据量大于PIPE_BUF时,Linux将不会再保证写入的原子性。FIFO缓冲区一有空闲区域,写进程就会试图向管道写入数据,写操作在写完所有的请求写的数据后返回。

2、对于没有设置阻塞标志的写操作:

   (1)当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。在写满所有的FIFO空闲缓冲区后,写操作返回;

   (2)当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性。如果当前FIFO空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;如果当前FIFO空闲缓冲区不能够容纳请求写入的字节数,则返回EAGAIN错误,提醒以后再写。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值