系统api-管道和FIFO

管道

没有名字标识,决定了只能用于父子进程间的IPC.半双工模式

int pipe(int fd[2]);

fd[0]用于读取,fd[1]用于写入.
在这里插入图片描述
上图为父子进程通过两个管道对象实现全双工通信的例子

FIFO

有名字标识,文件系统路径名,半双工模式.

// 默认包含O_CREAT | O_EXCL
int mkfifo(const char *pathname, mode_t mode);

使用模式:
(1). 用mkfifo创建FIFO对象,若返回EEXIST,再调open打开此已存在FIFO对象
(2). mkfifo创建成功后,依然用open来打开使用
(3). fifo是文件系统对象,删除需用unlink
fifo和管道不支持seek操作

非阻塞的指定

非阻塞的指定
(1). 对管道
fcntlF_GETFL,将返回结果添加O_NONBLOCK,再调fcntlF_SETFL,及更新后结果
(2). 对fifo
open时参数2指定O_NONBLOCK1中方法均可

FIFO比较晦涩的方面

以下均基于阻塞调用前提
(1). 打开申请
对一个指定的FIFO内核记录所有关联到此FIFO的进程访问请求.
对进程,执行对fifo对象某权限的open时,阻塞,条件满足才返回.
进程对fifoopen请求是否能满足取决于内核内核只在既收到对此fifo读打开请求,又收到对此fifo写打开请求时,才会对open请求进行满足,允许其按指定权限打开并返回.
可归纳为:
a. 初始时,内核等待同时有对某fifo对象的读打开请求和写打开请求时刻,才同时满足两个请求.再次之前,先到达的请求必须等待.多个不同进程发出的同类型请求均等待.直到某进程A发出另一请求,这时,前面等待的所有请求,和进程A的请求全部被满足,得以继续执行后续指令.
b. 后续,某请求请求以某权限打开此fifo,若此fifo已被以另一权限打开,则请求可被满足.否则,阻塞等待.

c. 对读打开fifo执行read,若FIFO内缓冲区有可读数据,进行读取返回.读取的数据不会超过缓冲区容量,也不会超过可读数据数量.若FIFO内缓冲区无数据可读,若,此时FIFO没有被写打开,读取失败,产生SIGPIPE信号.若,此时FIFO有被写打开,读取阻塞,等待.
d. 对写打开fifo执行写,若此FIFO没有被读打开,写入失败,产生SIGPIPE信号.若所写数据量小于PIPE_BUF,若FIFO可写空间可容纳写入数据,一次写入并返回.若FIFO可写空间小于待写入数据,阻塞等待.若所写数据量大于PIPE_BUF.若FIFO已满,返回错误.若FIFO未满,写入数据量取 要求写入的数据流和FIFO可写空间较小者.

终端read/write

(1). 终端底层由内核来对其维护
终端接收键盘输入,将输入信息存储在终端进程的缓冲区.
每次键入换行时,会将一行输入连同换行字符,放入缓冲区.每次键入Ctrl+D,产生一个EOF特殊字符,放入缓冲区.
(2). 对终端执行read时,终端依据read要求的数据量,依次从终端输入缓冲区取出字符,最多取要求数量的字符后,read返回.
特殊情况:
a. 取字符过程中若遇到\n,则从输入缓冲区取出此\n,且放入read指定缓冲区,此字符计入read获取的字符计数中.此后read返回.
b. 取字符过程中若遇到EOF(键入Ctrl+D产生的EOF是输入缓冲区一个字符),则EOF从输入缓冲区取出此EOF,但不放入read指定缓冲区,此字符不计入read获取的字符计数中.此后read返回.
c. 对终端执行write
对普通字符,显示其字符内容.对换行符,显示一个换行效果

关于EOF
a. 对终端,EOF也只是在其缓冲区中占据一个字节,EOF的特殊作用如上所述.但一旦EOF被取出生效,缓冲区EOF后仍然可放入正常字符并进行后续处理.
b. 对文件
文件在当前文件位置距离文件结束位置不足要求的读取数据量时,一次读完剩余数据并返回.后续再次read时,就是文件位置已经在结束位置然后继续读的情形,此时不论读多少次,每次都是以读0字节返回.
c. 对套接字
在缓冲区可读数据余量小于要求量但已经收到FIN时,一次读完余量返回.套接字只在收到对端的FIN时,且缓冲区已经没有可读数据时,返回0.此后,执行一次或多次read,每次都是以读取0字节返回.

字节流数据传输

(1). 管道/FIFO提供的是字节流数据传输服务
多个客户同时写一个管道/FIFO时,一般单个写入小于PIPE_BUF,对写入排队,顺序缓存写入信息.
(2). 从管道/FIFO读取信息
有时希望获取一个请求的边界.可采取方法:
a. 发送时以特殊字符作为一个请求终止符
接收时,先读取一块并缓存.在逐个扫描,扫描到终止符,即获得一个完整请求.
b. 每个请求按长度,内容组织.
读取时,先读取到长度,再按长度取完整请求内容.
c. 每次发起请求时,
均是建立连接,发起请求,断开连接. 一个请求一个连接,通过断开连接表示请求结束.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值