进程间的各种通信方式
1、无名管道(pipe):允许一个进程和另一个与它有共同祖先的进程(具有亲缘关系的进程)之间进行通信。特点:是一种特殊的文件,只存在于内存中;只能用于具有亲缘关系的进程间的通信;只能由一端向另一端发送数据,是半双工方式,如果双方需要同时收发数据需要两个管道。
2、有名管道(FIFO):类似于管道,但是它可以用于任何两个进程之间的通信,有名管道在文件系统中有对应的文件名,命名管道通过命令mkfifo或系统调用mkfifo来创建。特点:是FIFO文件,存在于文件系统中,可以通过文件路径名来指出;可以在不具有亲缘关系的进程间通信。
3、消息队列(MQ):消息队列是消息的连接表,包括POSIX消息对和System V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能成该无格式字节流以及缓冲区大小受限等缺点。相比于FIFO有以下优点:可以独立于读写进程存在,从而避免FIFO中同步管道的打开和关闭时可能产生的困难;避免FIFO的同步阻塞问题,不需要进程自己提供同步方法;读进程可以根据消息类型有选择地接收消息,而不像FIFO那样只能默认地接收。
4、信号量(semaphore):信号量主要作为进程间以及同进程不同线程之间的同步手段。多线程同步的信号量是POSIX信号量,而在进程里使用 SYSTEM V信号量。
5、共享内存(shared memory):它使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。这是针对其他通信机制运行效率较低而设计的,它往往与其他通信机制,如信号量结合使用,以达到进程间的同步及互斥。
6、信号(signal):信号是比较复杂的通信方式,用于通知接收进程有某种事情发生,除了用于进程间通信外,进程还可以发送信号给进程本身。
7、内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。共享内存的方式像极了多线程中线程对全局变量的访问,大家都对等地有权去修改这块内存的值,这就导致在多进程并发下,最终结果是不可预期的,所以对这块临界区的访问需要通过信号量来进行进程同步。 但共享内存的优势也很明显,首先可以通过共享内存进行通信的进程不需要像无名管道一样需要通信的进程间有亲缘关系,其次内存共享的速度也比较快,不存在读取文件、消息传递等过程,只需要到相应映射到的内存地址直接读写数据即可。
8、Socket:它是更为通用的进程间通信机制,可用于不同机器之间的进程间通信。