- pipe:无格式,限亲缘关系进程
- named pipe/FIFO:使用命名管道的所有进程都关闭,其数据结构从内存中消失。
- signal:异步方式,信息量小
- message queue:异步方式,适合通信频繁但是数据量的通信
- semaphore:实现进程间同步
- shared memory:为大数据量的进程间通信提供服务,最快最简单,但是需要其他IPC配合来防止出现竞争条件
- socket:不同于其他IPC都是同一主机内的进程通信,socket是跨主机,即网络内的不同主机内的不同进程间进行通信
其中message queue,semaphore,shared memory是基于System V IPC的进程间通信机制。这三种通信机制由内核管理维护一块用于通信的内存,不同的进程需要通信时会由内核来进行数据的复制,从而实现进程间的数据交换。
使用Sytem V进程间通信时,通信的数据统一放置在内核维护的IPC资源对象中。而这个IPC对象在系统中有唯一的标识符来区分,标识符的分配管理由内核负责,不同的进程就是通过相同的IPC标识符来通知内核提供进程间通信。
但是问题在于不同的进程怎么知道通过哪个IPC标识符来通信。于是内核又提供了一个叫做IPC键的值当作访问IPC对象的暗号,又称key。key是一个32 bit的数,需要通信的不同进程只要向内核提供相同的key,可以理解为钥匙,也可以理解为暗号,然后内核就会告诉进程你访问的这个IPC对象的标识符是多少多少,你们以后用这个IPC标识符来通信就可以了。形象一点,两个进程约定好用0x12345678这个key来找到统一个IPC对象,而0x12345678是可以随意指定的,只要你们提前约定好就可以。
那么问题又来了,你怎么能保证别的进程不会与你使用相同的key?所以比较合适的办法就不要像上面由程序员随意指定了,而是采取下面两个办法。
1.在获取IPC标识符时,使用常量0这个key,内核就创建一个IPC对象并返回IPC标识符,这个标识符保证唯一。拿到这个标识符的进程把标识符写入到指定文件,其他进程从制定文件中读取IPC标识符就可以了。
2.使用ftok函数,file to key,让内核将某个文件路径按照一定规则映射成一个key。不同进程使用相同文件映射出的key就会相同,那么提供给内核后返回的IPC标识符也就一致了。