简单点就是说,一个命令的结果作为另外一个命令(结果)的输入 。

管道是linux提供的一种常见的进程通信工具,也是很多shell命令能够灵活组合产生强大用途的一个重要工具。

管道是什么?

管道,顾名思义就是个管子,里面可以流过去很多东西。举个栗子 ls | morels输出列出来的文件目录就通过‘|’这个管道流向了more这个文本浏览器。相同的功能我们也可以通过ls > tmp ; tmp > more来完成。实际上管道的功能和第二个方法也很像。管道也是一个文件ls的输出送到这个文件,more再从这个文件将东西拿走。  所不同的是管道不同于普通的文件,是一套特殊的文件pipefs,在磁盘中没有映像,只在内存中存在,而且只存在于存在亲缘关系的进程之间。然后省略若干和文件系统,linux进程相关的知识…………好吧我还是说两句吧。

为什么是特殊的文件?

  我们知道有句传说是linux系统中一切皆文件,事实上这句话很忽悠人,虽然都是文件一个文本文件能和一个CPU设备一样么。实际上常用的特殊文件类型就有十多种,之所以要把他们都组织成文件是为了应用级别的程序员编程方便,不管操纵什么东西,文件、设备、socket等等都可以open之后read,write再close,可事实上调用的底层的系统程序是不一样的。这个想想也知道,写一个文本用的实际操作和往一个socket写东西怎么可能一样。pipe特殊就在于它是进程通信的一种方法,这种发法要保证一定的速度,所以就不好扔到硬盘上去读写了,干脆就直接在内存上读写了,所以它成为一个文件只是为了接口的方便。至于说它只在有亲缘关系的进程间共享,是因为管道属于进程打开的文件,只有创建管道的进程fork出来的子进程可以共享这个管道的文件描述符,其他无关系的进程是看不到这个管道的,所以说是一种非常狭隘小资的通信方式。

管道的创建

管道有两个口,一个入水口一个出水口。pipe系统调用会返回两个文件描述符,一个文件描述符用来写一个用来读。如上图所示,两个file结构指向同一个inode,对应管道在内存种所获得的一片区域。这里稍微要注意的一点是,尽管我们平时的应用都是一个管道对应一个写进程一个读进程,但是管道本身是支持多个进程进行读写的,他们只要对相同的描述符进行操作,加之系统的互斥进程就可以实现多进程的通信。这里也可以看出管道是半双工的,没有一个文件描述符可以用来进行读and写,如果想在两进程间进行全双工操作就开两条管道吧。

管道读写

前面说过了,不同的文件类型的write和read操作是不一样的,那么是怎么通过一个统一的write和read来找到对应的操作呢?看一下write函数的声明size_t write(int fd, const void *buf, size_t nbytes),从进程这边传过去的唯一一个可能区分文件类型的就是这个文件描述符fd了,也就是通过这个fd文件系统会找到它到底是哪个文件,再去采取相应的函数调用。当然如果是write操作的话还要涉及到一些对内存加锁的操作。

另一种管道FIFO

如果说管道有什么缺点的话,就是它只能在自家亲戚中使用,不利于社会共同富裕,没有关系的进程就无法通过管道进行勾搭了。于是内核打算采用一种实名制的方式来登记一下管道,这就是FIFO。

FIFO和pipe用的是同样的数据结构,同样的读写方式,不同的是内核为他们在磁盘注册了一个节点,这样所有进程都能看到这个硬盘上的节点,只要有权限就可以操作了,当然内容还是在内存中。并且这个实体可以用读写模式来打开,也就可以实现全双工了。

其他的话

上面都是一些机制的介绍。其实想写一下读源码的感受的,只是源码的感受过于琐碎,很难理出一个头绪来,而且源码的大框架是上面的机制,但看得时候注意到的更多是细节的实现方式,很多东西是和机制无关的。本以为这段的代码变更应该不会很大,但是看了一下commit记录发现变化还是很多的,很多新加的功能是除了注释找不到相关介绍的,只能自己从代码里推敲。还有一些改进方式是为了弥补以前的缺陷的,看这部分可以提升一些对系统整体的认识。所以鼓励大家在看过原理之后还是要看一下代码,代码中会有很多意外的收获,而这些收获又是很难通过别人讲述获得的

Linux 管道是什么 ?原理的更多相关文章

  1. linux管道命令grep命令参数及用法详解---附使用案例|grep

    功能说明:查找文件里符合条件的字符串. 语 法:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>] ...

  2. Linux数据包路由原理、Iptables/netfilter入门学习

    相关学习资料 https://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html http://zh.wik ...

  3. Linux管道的实现机制

    7.1.1 Linux管道的实现机制 在Linux中,管道是一种使用非常频繁的通信机制.从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现为: ...

  4. linux 管道--转

    linux 管道 管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别. ...

  5. Linux管道思想

    1.Linux管道 {{book | upper |lower | capfirst}} 含义:就是把前一个命令的结果当成后一个命令的输入.然后在下一个管道中输出满足条件的数据,如此继续数据的流向运动 ...

  6. linux管道详解

    原文链接:http://blog.csdn.net/qq_38646470/article/details/79564392 符号表示 | 和管道特别形象. 作用:     管道是Linux中很重要的 ...

  7. Linux入门-7 Linux管道、重定向以及文本处理

    Linux管道.重定向以及文本处理 1 Linux多命令协作:管道及重定向 管道和重定向 2 Linux命令行文本处理工具 文件浏览 基于关键字搜索-grep 基于列处理文本-cut 文本统计-wc ...

  8. 动态替换Linux核心函数的原理和实现

    转载:https://www.ibm.com/developerworks/cn/linux/l-knldebug/ 动态替换Linux核心函数的原理和实现 在调试Linux核心模块时,有时需要能够实 ...

  9. Linux管道及重定向

    Linux管道及重定向 对shell有一定了解的人都知道,管道和重定向是 Linux 中非常实用的 IPC 机制.在shell中,我们通常使用符合'|'来表示管道,符号'>'和'<'表示重 ...

  10. linux管道pipe详解

    linux管道pipe详解 https://blog.csdn.net/qq_42914528/article/details/82023408

随机推荐

  1. 画板(适用于手机、PC端)

    Html代码 <script type="text/javascript" src="jquery-1.9.1.min.js"></scrip ...

  2. ACM_小明滚出去?(求逆序数)

    小明滚出去? Time Limit: 2000/1000ms (Java/Others) Problem Description: 老师:“小明,写一个排序算法”: 小明: void mysort(i ...

  3. Spring Boot (1) 构建第一个Spring Boot工程

    Spring boot简介 spring boot是spring官方推出的一个全新框架,其设计目的是用来简化新spring应用的初始搭建以及开发过程. Spring boot特点 1.化繁为简,简化配 ...

  4. 自学Python八 爬虫大坑之网页乱码

    Bug有时候破坏的你的兴致,阻挠了保持到现在的渴望.可是,自己又非常明白,它是一种激励,是注定要被你踩在脚下的垫脚石! python2.7中最头疼的可能莫过于编码问题了,尤其还是在window环境下, ...

  5. Java接口中的成员变量为什么必须声明为public static final?

    我想对于每个Java程序员来说,接口都不陌生,接口中的方法也经常使用.而接口中的成员变量,就显得用得少一点,而对于成员变量为什么必须声明为public static final,可能就更不清楚了,而且 ...

  6. IE浏览器发展史

  7. SAP computer之program counter

    Program counter The program is stored in memory with the first instruction at binary address 0000, t ...

  8. 【sqli-labs】 less15 POST - Blind- Boolian/time Based - Single quotes (基于bool/时间的单引号POST型盲注)

    错误不回显了 构造永真登陆 登陆成功了 虽然登陆成功了,但是数据库的数据还么有爆出来 构造一下用户名 ' or length(database())=8# 如果数据库名的长度不等于8,登陆会失败 猜测 ...

  9. JQ 获取下一个元素和获取下一个元素的[指定]子元素

    <script type="text/javascript"> $(function () { $("#div1").next().addClass ...

  10. Linux 之常用操作指令详解

    1. 查看当做操作目录位置 > pwd 2. 查看(当前)目录里边的文件内容 > ls //list > ls -l 或ll //显示文件的详细信息 > ls -al //al ...