• 进程间通信(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按下回车键打开读端命名管道,写和读操作都将正常执行。同理,只打开读端而未打开写端命名管道时,读操作也会被阻塞。

  • 相关阅读:
    json转换成对象
    查看本机电脑的dns
    springboot整合jsp
    mysql DATE_FORMAT()函数用法
    checkbox全选反选
    mysql 中GROUP_CONCAT使用
    checkeds 选中获取tbale表格中某一列td标签中的值
    工具方法整理
    java开发微信公众号支付(JSAPI)
    Could not create connection to database server. Attempted reconnect 3 times. Giving up.错误
  • 原文地址:https://www.cnblogs.com/liujunjun/p/12411604.html
Copyright © 2020-2023  润新知