linux 管道

linux进程或者线程间通信的一种方式

管道本质上就是一个文件,前面的进程以写方式打开文件,后面的进程以读方式打开。这样前面写完后面读,于是就实现了通信

linux的设计思路就是一切皆文件,有着众多的文件系统

管道作为文件的存储地址是内存,所以可以认为Linux上的管道就是一个操作方式为文件的内存缓冲区。

管道的通信在同一时间是单向的,也就是一种半双工的形式,当一组数据被传入的时候,只有等到调用这组数据后才能再次传入。

在管道中没有数据的情况下,对管道的读操作会阻塞,直到管道内有数据为止。当一次写的数据量不超过管道容量的时候,对管道的写操作一般不会阻塞,直接将要写的数据写入管道缓冲区即可。

当然写操作也不会再所有情况下都不阻塞。这里我们要先来了解一下管道的内核实现。上文说过,管道实际上就是内核控制的一个内存缓冲区,既然是缓冲区,就有容量上限。我们把管道一次最多可以缓存的数据量大小叫做PIPESIZE。内核在处理管道数据的时候,底层也要调用类似read和write这样的方法进行数据拷贝,这种内核操作每次可以操作的数据量也是有限的,一般的操作长度为一个page,即默认为4k字节。我们把每次可以操作的数据量长度叫做PIPEBUF。POSIX标准中,对PIPEBUF有长度限制,要求其最小长度不得低于512字节。PIPEBUF的作用是,内核在处理管道的时候,如果每次读写操作的数据长度不大于PIPEBUF时,保证其操作是原子的。而PIPESIZE的影响是,大于其长度的写操作会被阻塞,直到当前管道中的数据被读取为止。

Linux上的管道分两种类型:

  1. 匿名管道
  2. 命名管道

匿名管道只能在父子进程或者父子线程之间使用,因为这些进程或者线程有着相同的内存信息,因此管道信息也在其中保存,可以用来进行通信,使用pipe()创建

使用pipe()系统调用可以创建一个匿名管道,这个系统调用的原型为:

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

这个方法将会创建出两个文件描述符,可以使用pipefd这个数组来引用这两个描述符进行文件操作。pipefd[0]是读方式打开,作为管道的读描述符。pipefd[1]是写方式打开,作为管道的写描述符。从管道写端写入的数据会被内核缓存直到有人从另一端读取为止

有名管道相当于是一个文件,mkfifo创建,任何的进程或线程只要有这个文件名就可以进行操作

管道的使用和删除都可以使用文件操作,open write read unlink,unlink()会删除参数pathname 指定的文件. 如果该文件名为最后连接点, 但有其他进程打开了此文件, 则在所有关于此文件的文件描述词皆关闭后才会删除. 如果参数pathname 为一符号连接, 则此连接会被删除。

 

posted @   纸包鱼  阅读(200)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
点击右上角即可分享
微信分享提示