zoukankan      html  css  js  c++  java
  • 进程间通信(2):管道

    管道

    管道是操作系统提供的一种最基本的进程间通信方式。每创建一个管道,就有两个文件描述符,一个是负责读管道的,一个是负责写管道的。所以,使用管道通信时,可以看作是两个文件描述符加一段内核空间中的内存,如图。

    管道只能协调有亲缘关系的进程间通信,所谓亲缘,比如父子进程、兄弟进程。当某进程创建一个管道后,它就拥有了这个管道的两个文件描述符,它的子进程会继承这两个文件描述符,所以子进程也能读写这个管道。如图。

    但为了让管道通信更安全、更方便,一般管道两端的每个进程都会各自关闭一个管道的文件描述符,例如父进程关闭读描述符,这样父进程只能向管道写数据,子进程关闭写描述符,这样子进程只能从管道读数据。或者相反。如图。

    Shell也提供了管道,只需使用一根竖线连接两个命令即可。例如:

    [root@docker-03 ~]# ps -elf | grep "sshd"
    4 S root        939      1  0  80   0 - 26519 poll_s 18:15 ?        00:00:00 /usr/sbin/sshd -D
    4 S root       1306    939  0  80   0 - 37099 poll_s 18:16 ?        00:00:00 sshd: root@pts/0
    0 S root       1417   1308  0  80   0 - 28182 pipe_w 19:23 pts/0    00:00:00 grep --color=auto sshd
    [root@docker-03 ~]# cat a.log | grep "hello world"

    在shell下,这种管道称为匿名管道,即没有名称的管道。它对于编写命令行来说非常方便,且逻辑清晰易懂,shell脚本和shell命令行几乎靠它打下了半壁江山。

    在shell下,还支持使用mkfifo命令创建命名管道(named pipe),即有名称的管道,它也称为FIFO,它可以协调任意进程间的数据通信。

    例如,创建命名管道文件a.fifo,a.fifo就是这个命名管道的名称。虽然它以文件的方式存在于磁盘上,但它传递数据的方式不会经过磁盘IO,而是直接在内存中传递,所以速度非常快,文件名仅仅只是这个命名管道的名称而已,是引用这个管道的入口和出口。

     
    1
    2
    3
    $ mkfifo a.fifo
    $ ls -l a.fifo
    prw-r--r-- 1 root root 0 Apr 30 23:52 a.fifo # 文件类型为p

    命名管道是阻塞式的双向通信管道,任意一方都可以读、写,但是只有读、写端同时打开了命名管道时,数据才会写入并被读取。例如,下图中显示了在未打开读端命名管道的时候,所有写命名管道的操作都被阻塞。如果cat a.fifo按下回车键打开读端命名管道,写和读操作都将正常执行。同理,只打开读端而未打开写端命名管道时,读操作也会被阻塞。

  • 相关阅读:
    mysql 应用 持续更新2 转载
    sql server 用触发器记录增删改操作(转载)
    mysql 应用 持续更新
    oracle 常用指令(持续更新中....)
    转载-Oracle 数据库导入导出 dmp文件
    Web Service 服务无法连接Oracle数据库
    关于jquery获取服务器端xml数据
    Navicat Premium 自动备份mysql和sqlserver
    浅谈如何更好的打开和关闭ADO.NET连接池
    JSON 的优点
  • 原文地址:https://www.cnblogs.com/liujunjun/p/12411604.html
Copyright © 2011-2022 走看看