运行结果如下:
文章插图
匿名管道读写规则
文章插图
读写规则总结:
- 当没有数据可读时O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止 。O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN 。
- 当管道满的时候O_NONBLOCK disable: write调用阻塞,直到有进程读走数据O_NONBLOCK enable:调用返回-1,errno值为EAGAIN
- 如果所有管道写端对应的文件描述符被关闭,则read返回0
- 如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程退出
- 当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性
- 当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性
管道特点(了解)
- 只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道 。
- 管道提供流式服务 。也就是你想往管道里读写多少数据是根据自身来定的
- 一般而言,进程退出,管道释放,所以管道的生命周期随进程
- 一般而言,内核会对管道操作进行同步与互斥
- 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道
- 半双工是指传输过程中同时只能向一个方向传输,一方的数据传输结束之后,另外一方再回应 。双方传输数据是不可以同时进行的
- 全双工是指两方能同时发送和接受数据 。在这种情况下就没有拥堵的危险,数据的传输也就更快
命名管道不同于无名管道之处在于它提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中,这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信,因此,通过FIFO不相关的进程也能交换数据 。
- FIFO在文件系统(磁盘上)中作为一个特殊文件而存在,但是FIFO中的内容却存放在内存中 。
- 当使用FIFO的进程退出后,FIFO文件将继续保存在文件系统中以便以后使用 。
- FIFO有名字,不相关的进程可以通过打开命名通道进行通信 。
mkfifo filename
2.通过函数创建命名管道
int mkfifo(const char *pathname, mode_t mode);
功能:创建命名管道
参数:pathname:普通的路径名,也就是创建后FIFO的名字 。
?mode:文件的权限,与打开普通文件的open函数中的mode参数类似 。
返回值:成功:0 (状态码)失败:如果文件已经存在,则会出错返回-1
代码示例:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#define FIFO "./fifo"int main(){umask(0);// 创建管道int ret = mkfifo(FIFO, 0666);if (ret == -1){perror("make fifo");exit(-1);}}
运行结果如下:文章插图
上面说过,管道其实就是一种特殊的文件,管道文件大小是0,因为上面介绍过,管道文件的内容都存放在内存当中 。
经验总结扩展阅读
- 一篇了解全MVCC
- 2022感恩节是在什么时候 2022年感恩节日期是哪一天几月几日
- 治疗二型糖尿病偏方
- 鬼针草治疗高血压偏方
- 2022美国感恩节是哪一天 2022美国感恩节有几天假期
- 2023年感恩节是几月几号 2023年感恩节是哪一天
- 酒后反胃恶心吐怎么办
- 最经典早安祝福语
- 哺乳期吃了一个脏脏包对孩子有什么影响
- 早安问候文案唯美