Interprocess Communications
消息传递
管道
匿名管道随进程的创建而建立,随进程的结束而销毁
管道是基于Linux & Unix的操作系统的核心概念之一。管道允许您以一种非常优雅的方式 | 将命令链接在一起,将一个程序的输出传递为另一个程序的输入。
1 | ls -la | sort | less |
bash 的执行过程
bash创建2个管道,一个从ls到sort,一个从sort到lessbashfork三个子进程分别用于每个命令- 子进程1
ls设置stdout为pipe A的写端 - 子进程2
sort设置stdin为pipe A的读端,设置stdout为pipe B的写端 - 子进程3
less设置stdin为pipe B的读端
Linux has a VFS (virtual file system) module called
pipefs, that gets mounted in kernel space during boot.pipefsis mounted alongside the root file system (/), not in it (pipe’s root ispipe:).pipefsis stored using an in-memory file system.
pipefscannot be directly examined by the user unlike most file systems. The entry point topipefsis thepipesyscall. Thepipesyscall is used by shells and other programs to implement piping, and just creates a new file in pipefs, returning two file descriptors (one for the read end, opening usingO_RDONLY, and one for the write end, opened usingO_WRONLY).![]()
使用 fork 创建子进程,创建的子进程会复制父进程的文件描述符,这样就做到了两个进程各有两个 fd[0] 与 fd[1],两个进程就可以通过各自的 fd 写入和读取同一个管道文件实现跨进程通信。
父子进程间的单向数据流(半双工管道)
1 |
|
父子进程间的双向数据流的两个管道(全双工管道,有两个半双工管道构成)
1 |
|
FIFO
名字空间
当两个或多个无亲缘关系的进程使用某种类型的IPC对象来彼此交换信息时,该IPC对象必须有一个某种形式的 名字(name) 或 标识符(identifier) ,这样其中一个进程(往往是服务器)可以创建该IPC对象,其余进程则可以指定同一个IPC对象
管道没有名字,因此它们的最大劣势就是智能用于有一个共同祖先进程的各个进程之间。而 FIFO(指代first in, first out) 类似于管道(单向数据流),且有一个文件路径名与之关联从而实现无亲缘关系进程访问同一个FIFO,所以也被称为 命名管道(named pipe)
Any FIFO is much like a pipe: rather than owning disk blocks in the filesystems, an opened FIFO is associated with a kernel buffer that temporarily stores the data exchanged by two or more processes. Thanks to the disk inode, however, a FIFO can be accessed by any process, since the FIFO filename is included in the system’s directory tree. FIFO inodes appear on the system directory tree rather than on the pipefs special filesystem.
![]()
Allocates a
pipe_inode_infoobject (the actual pipe) for providing buffer space when fifo_open(…)![]()
通过 mkfifo 命令来创建并指定管道名字
1 | mkfifo myFifo |
消息队列
随内核的持续性
消息队列可认为时一个消息链表,有足够写权限的线程可往队列中放置消息,有足够读权限的线程可从队列中取走消息。
每个消息都具有如下属性:
- 一个无符号整数优先级(Posix) / 一个长整数类型(System V)
- 消息的数据部分长度
- 数据本身
System V 消息队列
1 |
|
Posix 消息队列
POSIX message queues implement priority-ordered messages. Each message written by a sender process is associated with an integer number which is interpreted as message priority; messages with a higher number are considered higher in priority.
![]()
1 |
|
区别
- 对Posix消息队列的读总是返回最高优先级的最早消息,对SystemV消息队列的读则可以返回任意优先级的消息
- 当往一个空队列放置一个消息时,Posix消息队列允许产生一个信号或启动一个线程,SystemV消息队列则不提供类似机制