6. 没有人真正见过的进程通信
Introduction
匿名/实名管道
信号
消息队列
共享内存
信号标
socket
匿名/实名管道
Linux管道分成了匿名与实名两种, 所谓实名是因为他真的创建了一个类型为pipe的文件, 不同的进程通过open, read, write这个文件达到相互通信的目的, Linux最常见的匿名管道是竖线|
比如ls | grep
, ls出来的结果就通过这个管道传到grep里去
与实名管道相对的是匿名管道, 匿名管道本质上是你程序里定义出的变量, 这个变量本质上是一个由VFS实现的fd.
因为是你程序定义出来的变量, 因此只有你与你的子进程能看到/访问到这个变量, 父子进程间通过这个管道相互通信
因为是VFS实现的, 因此不落盘, 仅仅存在于内存里, 一旦内存结束匿名管道以及管道里的消息就会彻底消失不见
实际使用中你通过Pipe函数初始化一对int, 即一对文件描述符, 一端是写入, 另一端是读取, 值得注意的是读取/写入都是阻塞的. 有点类似go语言里长度为0的chanel,
Linux消息队列
另一种常见的手段是使用消息队列, 你通过msg_get来创建/打开一个现有的队列, 并使用msg_send/recv来收发, 除了这些基础的用法, 还有msg_ctl来管理这个消息队列, 管道与消息队列都是信息的载体, 区别在于:
管道是同步的, 消息队列是异步的, 也就是说消息队列你可以丢一条消息进去就走, 从这一点上看, 二者很像golang里面有/无缓冲区的chanel
管道只能由指定的一端写入, 另一端读取, 而消息队列你可以从任意位置开始读/写
管道内的消息没有优先级与权重, 而消息队列里的消息是有权重的
管道内的消息一旦程序结束了, 管道内的消息就没了, 而消息队列是内核负责维护的, 消息是一直都在的
这样看消息队列一定优于管道, 而管道一直存在的原因除了管道比较早以外, 也同样因为他的阻塞性.
Last updated
Was this helpful?