Linux几乎支持全部UNIX进程间通信方法,包括管道(有名管道和无名管道)、共享内存、消息队列、信号、信号量和套接字。其中套接字是用于不同主机在网络中的通信。
- 管道:
- 无名管道(内存文件):管道是一种半双工的通信方式,数据只能单向流动,也就是在同一时刻只能由管道的一端向另一端发送数据,另一端进行接收。而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常指父子进程或兄弟进程。
- 有名管道(FIFO文件,借助文件系统):有名管道也是半双工的通信方式,但是允许在没有亲缘关系的进程之间使用;管道是先进先出的通信方式。
- 共享内存:共享内存就是映射一段能被其它进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的进程间通信方式,它是针对其它进程间通信方式运行效率低而专门设计的。它往往与信号量配合使用来实现进程间的同步和通信。
补充
- 共享内存的方式像极了多线程中线程对全局变量的访问,每个线程都有权去访问或修改这块内存的值;这就导致在多进程并发下,最终这块内存的结果是不可预期的。所以对这块临界区的访问需要通过信号量加锁机制来进行进程同步。
- 但共享内存的优势也很明显,首先可以通过共享内存进行通信的进程不需要像无名管道那样要求进程间有亲缘关系;其次内存共享的速度也比较快,不存在读取文件、消息传递等过程,只需要到相应映射到的内存地址直接读写数据即可。
- 消息队列:消息队列是有消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
- 套接字:适用于不同机器间的进程通信,在本地也可以作为两个进程间通信的方式。
- 信号:用于通知接收进程某个事件已经发生,比如在终端输入ctrl + c 就是一个信号。
- 信号量:在提到共享内存方式的时候也说到了信号量,进程共享内存和多线程共享全局变量非常相似。所以在使用共享内存的方式进行进程间通信时也需要通过信号量来完成进程间同步。多线程同步的信号量是 POSIX 信号量,而在进程里使用的是 SYSTEM V 信号量。
// 参考拓跋阿秀公众号。