主要有如下方式:管道、信号、消息队列、共享内存、信号量、套接字,本文选择几种大概介绍,后续会对比较重要的专门发文介绍。
1.管道
管道分为有名管道和匿名管道,匿名管道只能在有亲缘关系的进程间通信,有名管道克服这个缺点。
值得注意的是,只有在管道有读端时,往管道中写数据才有意义。否则,向管道写数据的进程会接收到内核发出来的SIGPIPE信号;应用程序可以自定义该信号处理函数,或者直接忽略该信号。
read(pipefd),如果管道为空,且没有写端,直接返回0.
2.信号
信号是Unix系统中使用的最古老的进程间通信的方法之一,OS通过信号来通知某一进程发生了某一种预定好的事件;接收到信号的进程可以选择不同的方式处理该信号,一是可以采用默认处理机制-进程中断或退出,一是忽略该信号,还有就是自定义该信号的处理函数,执行相应的动作。
3.共享内存
共享内存是IPC最快的,一旦这样的内存区域映射到共享它的进程的地址空间,这些进程间的数据传递就不在涉及内核。然而往该共享内存区存放信息或从中取走信息的进程通常需要某种形式的同步。 这里说的“不涉及内核”的含义是:进程不再通过执行任何进入内核的系统调用来彼此传递数据。显然,内核必须建立允许各个进程共享该内存区的内存映射关系,然后一直管理该内存区。
4.消息队列前面我们说到,管道如果没有读出者在,写入者是没有意义的。然后消息队列却不同,在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达(即读取消息)。
一个进程可以往消息队列写入一些消息,然后终止,再让另外一个进程在以后某个时刻读出这些消息。因为消息队列具有随内核的持续性,这跟管道是不同的,当一个管道关闭的时候,管道中的数据将丢弃。