这篇文章简单介绍一下操作系统中的管道,并主要解决以下两个问题:

1、管道的内部实现

2、管道的容量?

管道是操作系统中,不同进程之间进行通信的方式。

根据通信的进程之间的关系,管道分为匿名管道和非匿名管道

其中,匿名管道只能用于有“血缘关系”的进程之间进行通信,而命名管道则可以用于任意两进程的通信

此外,管道是单向的,所以2个管道就可以实现进程之间的双向通信

管道的实现原理:

我们知道,进程之间的数据是私有的,即使是父子进程,也是如此,所以,要想让2个进程共享某个数据,我们可以在指定的路径下创建一个文件,然后其中一个进程将要传输的数据写入这个文件,另一个进程读取这个文件的信息,就可以实现进程之间的通信了,当然,考虑到效率,这一切通常是不可能发生在磁盘上的。

此外,由于一些机制,管道提供“流式”服务,对具体一次写入多少数据,一次读取多少数据,都不需要严格的规定

在Linux下,管道的实现没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。

通过两个file结构指向同一个临时的VFS索引节点,而这个VFS索引节点又指向一个物理页面而实现的。

如下图:

上图中有两个file数据结构,但他们定义文件操作例程地址是不同的,其中一个是向管道中写入数据的例程地址,另一个是从管道中读取数据d例程地址。

这样,用户程序系统调用仍然是通常的文件操作,而内核却利用这种抽象机制实现了管道这一特殊的操作。

//inode结点信息结构

struct inode {

...

struct pipe_inode_info  *i_pipe;

...

};

//管道缓冲区个数

#define PIPE_BUFFERS (16)

//管道缓存区对象结构

struct pipe_buffer {

struct page *page; //管道缓冲区页框的描述符地址

unsigned int offset, len; //页框内有效数据的当前位置,和有效数据的长度

struct pipe_buf_operations *ops; //管道缓存区方法表的地址

};

//管道信息结构

struct pipe_inode_info {

wait_queue_head_t wait; //管道等待队列

unsigned int nrbufs, curbuf; //包含待读数据的缓冲区数和包含待读数据的第一个缓冲区的索引

struct pipe_buffer bufs[PIPE_BUFFERS]; //管道缓冲区描述符数组

struct page *tmp_page; //高速缓存区页框指针

unsigned int start;  //当前管道缓存区读的位置

unsigned int readers; //读进程的标志,或编号

unsigned int writers; //写进程的标志,或编号

unsigned int waiting_writers; //在等待队列中睡眠的写进程的个数

unsigned int r_counter; //与readers类似,但当等待写入FIFO的进程是使用

unsigned int w_counter; //与writers类似,但当等待写入FIFO的进程时使用

struct fasync_struct *fasync_readers; //用于通过信号进行的异步I/O通知

struct fasync_struct *fasync_writers; //用于通过信号的异步I/O通知

};

至于上文提到的VFS对象,在linux2.6以后的版本中,把这些对象组织成pipfs特殊文件系统以加速它们的处理

管道的容量:

如果管道被写满了,这时候写端就不会向管道再继续写入数据了

那么管道的容量具体是多大呢?

实际使用中,还有两个概念对理解管道至关重要。一个是管道容量。另一个是管道操作原子性。

管道容量有限。如果管道满,阻塞方式下write操作会阻塞,非阻塞方式下会返回失败。不同的系统有不同的管道容量限制。应用模块不应该依赖特定 的容量限制,正确的设计是:一旦数据到达进程应尽快消费数据,避免写进程长时间阻塞。从linux 2.6.11版本开始,管道容量是65536字节。

POSIX 1-2001规定向管道写小于PIPE_BUF字节长度的数据时原子操作;写超过PIPE_BUF字节长度的数据不是原子操作。Linux上PIPE_BUF是4096字节,更细致的描述:

1、阻塞方式,n<=PIPE_BUF(n为写入的字节数,下同):写操作是原子操作,如果pipe空间不足则阻塞。

2、非阻塞方式,n<=PIPE_BUF:写操作是原子操作,如果pipe空间不足,则失败,errno设置为EAGAIN。

3、阻塞方式,n>PIPE_BUF:写操作不是原子操作,写入的数据可能与其他进程写入的交叉排列,写操作阻塞直到所有数据写完。

4、非阻塞方式,n>PIPE_BUF:写操作不是原子操作,如果pipe空间不足,则失败,errno设置为EAGAIN。写入的数据可能与其他进程写入的数据交叉排列。同时实际写入可能小于n(部分写入);调用者应该检查write实际写入的长度。三个概念:

1、页缓冲区大小:4K

2、总缓冲区大小:64K

1、<4K的数据立即发送,以页为单位

2、>4K的数据,将会分成多个页的数据,分批发送。

函数 write要么阻塞,要么成功(copy全部数据到内核缓冲区,不存在只copy部分数据的情况),异常换回-1

参考:

(linux管道容量的测试)

(linux管道的实现机制)

linux系统应用管道展望,linux学习——管道相关推荐

  1. 2021-04-04:linux第1天:linux系统的基础介绍及学习

    1.Linux学习方向 linux运维工程师:是维护linux环境服务器的 linux嵌入式工程师:下面做驱动开发和linux嵌入式系统下面做开发 linux下面做开发项目:一般是写java程序,放在 ...

  2. 嵌入式学习之linux系统编程----1 了解linux编程并且在ubuntu以及ARM上运行测试程序

    1.何为linux系统编程? linux系统编程也称为linux下的高级编程,它介于应用层与驱动层之间. 一般来说分为三个层面,分别是:应用层(写一个qt程序或者c程序就属于是应用层面).驱动层(比如 ...

  3. linux系统charp命令,操作系统 Linux系统

    Linux操作系统 预备知识(Operating System): 1.GNU项目,GNU项目是一个自由软件项目,旨在建立一个完全自由开放通用的UNIX软件平台. 2.操作系统:管理计算机硬件和软件资 ...

  4. linux系统查看串口占用,Linux 系统串口信息查看

    先确认系统启动的时候串口的信息. ECM_5412@chenfl:~$ dmesg | grep tty [ 0.000000] console [tty0] enabled [ 2.511678] ...

  5. php 登录 linux服务器,如何实现linux系统远程登录到linux服务器

    linux系统登录到远程linux服务器: 有多种不同的协议可供选择,也许SSH是"最好"的.SSH是secure shell的简写,意为"安全的shell". ...

  6. Linux系统磁状态检测,检测Linux硬件状态

    计算机系统是由软件系统和硬件系统共同组成的.检测硬件状态对于保障整个系统的稳定是非常重要的.不论操作系统是使用Linux.还是Windows,一旦硬件出现故障,那么整个系统的安全就严重了.这里我们主要 ...

  7. git 的安装以及使用:是一个开源的分布式版本控制系统,可以对项目进行版本管理。 早期是linux之父用来管理linux系统源代码的(linux是和windows一样操作系统 开源免费的操作...

    ## 总结 - 学会使用基本的git命令 管理源代码 - 学会去github创建仓库 并将代码上传到github的仓库 (有待完成 回家有网再push) - 了解本地的.git和服务器github的. ...

  8. 如何查看linux系统的存储空间大小,linux 如何查看硬盘大小,存储空间大小等系统信息及硬件信息...

    一.linux CPU大小 [root@idc ~]# cat /proc/cpuinfo |grep "model name" && cat /proc/cpui ...

  9. 如何制作linux系统硬盘,手把手带你自制Linux系统之二 简易Linux的制作

    手把手带你自制Linux系统之二 简易Linux的制作 本文利用CentOS5.5自带内核制作一个可以正常启动的Mini Linux. 打开上一篇准备工作中创建的CentOS虚拟机,为另一台虚拟机Mi ...

  10. Linux系统-小倒腾之Linux DIY定制裁剪(New kernel+Busybox)o_o(二)

    在前面的<Linux系统-小倒腾之Linux DIY定制裁剪(附带简单网络功能)o_o(一)>博文中,我通过对一个Linux系统的裁剪,最终制作出来了一个带有网络功能的微型Linux系统; ...

最新文章

  1. CUDA中grid、block、thread、warp与SM、SP的关系
  2. 搭建elasticsearch测试工程
  3. linux系统shell知识点,Linux 系统中shell知识点说明和常用的帮助命令简单介绍 | IT工程师的生活足迹...
  4. Oracle 索引失效的六大限制条件
  5. conda install 报错PackagesNotFoundError: 以及和合理使用源的策略
  6. linux 服务状态命令,Linux 查看服务列表,查看服务状态
  7. 中年失业是一种什么体验
  8. Ruby快速入门(30分钟)
  9. win10自带录屏工具
  10. 健康体检信息系统源码、医院体检源码 医院管理系统源码
  11. 农历和阳历日期互转,Python实现
  12. 《Python程序设计基础 》课堂笔记整理
  13. 【Windows】windows10,11系统常用快捷键
  14. 中国石油大学《大学英语(三)统考》第二套模拟题
  15. 微信小程序提现到零钱
  16. Java中File文件类之文件过滤器
  17. 云计算笔记---day3
  18. javascript 知识
  19. css玻璃雨滴效果,纯css实现窗户玻璃雨滴逼真效果
  20. 第五十五讲 插件设备树

热门文章

  1. 天猫复购预测 - rank 7 , top 0.16%
  2. 你能战胜自己:克服自卑的方法
  3. SQL Server中视图,存储过程,注入
  4. 如何实现EXCEL的快速下拉
  5. 基于Python实现个人手机定位分析
  6. linux AT T Assembly
  7. POJ 1673 EXOCENTER OF A TRIANGLE(解三角形重心)
  8. 遇到问题,有哪些有效的分析方法?
  9. python画五角星代码_Python如何使用27行代码绘制星星图
  10. java计算机毕业设计springboot+vue在线投票系统