进程间通信的方式的方式有:管道、消息队列、信号量、共享内存、socket。
管道
管道是半双工(数据可以在一个信号载体的两个方向上传输,但是不能同时传输)的,其中又分为匿名管道、命名管道两种,其中匿名管道只能用于具有亲缘关系的进程间通信,命名管道无这种限制。
消息队列
消息队列的本质其实是一个内核提供的链表,内核基于这个链表,实现了一个数据结构,并且通过维护这个数据结构来维护这个消息队列。向消息队列中写数据,实际上是向这个数据结构中插入一个新结点;从消息队列汇总读数据,实际上是从这个数据结构中删除一个结点。
linux下可用ipcs -q命令查看已创建的消息队列
信号量
用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。
分类
- 整型信号量:信号量为一个整数
- 记录型信号量:每个信号量s除一个整数值s.value(计数)外,还有一个进程等待队列s.L
- 二进制信号量:只允许取0或1,与互斥锁有点类似
共享内存
所谓共享内存就是使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。
使用场景
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。其他进程能把同一段共享内存段“连接到”他们自己的地址空间里去。
特性
所有进程都能访问共享内存中的地址。如果一个进程向这段共享内存写了数据,所做的改动会即时被有访问同一段共享内存的其他进程看到。
注意
共享内存的使用大大降低了在大规模数据处理过程中内存的消耗,但是共享内存的使用中有很多的陷阱,一不注意就很容易导致程序崩溃。
socket
也称套接字,有流式套接字(TCP协议的套接字)、数据报套接字(UDP协议的套接字)、原始套接字
根据其用途还可分为主动套接字和被动套接字两种,其中主动套接字用于发起连接的(connect),被动套接字用于接受连接(listen后)
用途
一般用于网络通信,不同计算机之间的通信(使用INET协议族),也可用于本机进程间通信(UNIX协议族更快)