进程通信学习笔记(管道)

1、管道

pipe函数创建单向数据流

#include <unistd.h>
int pipe(int fd[2]);

成功返回0,失败返回-1

该函数返回两个文件描述字:fd[0]和fd[1],fd[0]打开来读,fd[1]打开来写

用途时提供两个不同进程(一个是父进程,一个是子进程)间的通信手段。首先,由一个进程(父进程)创建一个管道后调用fork派生一个自身的拷贝


2、popen和pclose

popen创建一个管道并启动另外一个进程,该进程或者从该管道中读出标准输入,或者往该管道写入标准输出

#include <stdio.h>
FILE *popen(const char *command, const char *type);

成功返回文件指针,失败返回NULL

int pclose(FILE *stream);

成功返回shell的终止状态,失败返回-1

command是shell命令行。popen在调用进程和所指定的命令之间创建一个管道。由popen返回的值是一个标准I/O FILE指针,该指针或者用于输入,或者用于输出,具体取决于字符串type

如果type为r,调用进程读进command的标准输出

如果type为w,调用进程写到command的标准输入


3、FIFO

无亲缘关系的进程可以用它创建彼此间的管道。是一个单向(半双工)数据流,每个FIFO有一个路径名与之关联,也称作有名管道。FIFO用mkfifio函数创建,其函数原型为

#include <sys/types.h>
#include <sys/stat.h>

int  mkfifo(const char *pathname, mode_t mode);

成功返回0,失败返回-1

pathname是一个普通的Unix路径名,它是该FIFO的名字

mode参数指定文件权限位,类似于open的第三个参数。定义在<sys/stat.h>头文件中的用于给一个FIFO指定权限位的6个常值 

mkfifo函数已隐含指定O_CREAT|O_EXCL。也就是说,它要么创建一个新的FIFO,要么返回一个EEXIST错误。如果不希望创建一个新的FIFO,就改为open。

FIFO不能打开既读又写,因为它是半双工的。对管道或FIFO的write总是往末尾添加数据,read则总是从开头返回数据,如果对管道或FIFO调用lseek,返回ESPIPE错误

管道在将它打开着的进程中最后一个关闭它之后自动消失,FIFO的名字只有通过调用 unlink才从文件系统中删除

使用FIFO的顺序很微妙,如果当前尚没有任何进程打开某个FIFO来写,那么打开该FIFO来读的进程将阻塞


4、管道和FIFO的额外属性

设置非阻塞方式的两种方式

(1)调用open指定O_NONBLOCK标志

(2)如果描述字已经打开,调用fcntl使能O_NONBLOCK

非阻塞标志对于打开一个FIFO的影响、对于从一个空管道或空FIFO读出数据的影响以及对于往一个管道或FIFO写入数据的影响:


读出或写入的几个规则:

(1)如果请求读出的数据量多于管道或FIFO中当前可用数据量,只返回这些可用的数据。但是必须处理来自read的小于所请求数目的返回值 

(2)如果请求写入的数据的字节数小于或等于PIPE_BUF,那么write操作保证是原子的。如果请求写入的字节数大于PIPE_BUF,那么write操作不能保证是原子 的

(3)O_NONBLOCK标志的设置对于write的原子操作没有影响--原子性操作完全是由所请求字节数是否小于等于PIPE_BUF决定的。然而当一个管道或FIFO设置成非阻塞时,来自write的返回值取决于待写的字节数以及该管道或FIFO中当前可有空间的大小。

如果待写的字节数小于等于PIPE_BUF:

       (a)如果管道或FIFO中有足以存放请求字节数据的空间,那么所有数据字节都写入

(b)如果管道或FIFO中没有足以存放所请求字节数的空间,那么立即返回一个EAGAIN错误

如果待写的字节数大于PIPE_BUF:

(a)如果管道或FIFO中至少有一个字节空间,内核写入能容纳的数据字节,该数目同时作为来来自write的返回值 

(b)如果管道或FIFO已满,立即返回EAGAIN错误

如果写入一个没有打开着用于读的管道或FIFO,将产生一个SIGPIPE信号

(a)如果调用进程既没有捕获也没有忽略SIGPIPE信号,缺省行为是终止该进程

(b)如果进程忽略SIGPIPE信号或捕获该信号并从信号处理程序返回,write返回一个EPIPE错误


5、管道和FIFO限制

加于管道和FIFO的唯一限制:

OPEN_MAX:一个进程在任意进户可以打开的最大描述字

PIPE_BUF:可原子地写往一个管道或FIFO的最大数据量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kgduu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值