Linux进程间通信总结

刚请完婚假,请假期间做了些技术总结,其中一个就是Linux进程间通信方式的总结。

Linux提供了多种进程间通信的方式,列举如下:

  • PIPE(管道)
  • FIFO(先进先出,也称为有名管道)
  • domain_socket(域套接字)
  • XSI-semaphore(XSI信号量)
  • XSI-message_queue(XSI消息队列)
  • XSI-shared_memory(XSI共享内存)
  • POSIX-semaphore(POSIX信号量)
  • mutex(互斥量)

其中semaphore和互斥量虽然是进程或线程间的同步方式,但是同步其实本质上也是通信的一种,所以这里也一并列出来。

PIPE

管道是最古老也是最常用的进程间通信方式,我们在Linux命令行中使用的ls | grep crond就是使用管道将前一个进程的输出重定向为后一个进程的输入。管道主要的缺点是:

  1. 只能用于父子或其它有共同祖先的进程之间;
  2. 是单工通信。

FIFO

为了克服管道只能用于父子进程间的缺点,引入了有名管道,又称为先入先出队列。FIFO的操作方式与普通文件类似,但是必须同时有写端和读端才可操作。

相对于PIPE,FIFO的主要改进是:

  1. 可以用于任意两个进程之间
  2. 可以通过FIFO文件的属性来控制访问权限

Domain Socket

域套接字是一种类似于网络套接字的通信方式,但是专门用于同一台主机的两个进程之间,它是一种双工的通信方式。

XSI Semaphore

XSI是X/Open System Interfaces的缩写,是一种系统接口的标准,它规定了三种通信方式,即semaphore、message queue、shared memory,它们有一致的编程接口。Linux系统上可以使用两种形式的信号量,一种是这里说的XSI_semaphore,还有一种是POSIX_semaphore,后面再解释什么是POSIX_semaphore。

在非必须的情况下,个人不推荐使用XSI进程间通信的方,因为它比较复杂。除了共享内存之外,另外两种XSI进程间通信方式都有其它的替代方法。XSI进程间通信的大致流程如下:

  1. 两个进程获取一个key
  2. 两个进程使用这个key来获取进程间通信的ID
  3. 两个进程进行进程间通信
  4. 其中一个进程释放进程间通信的ID

最麻烦的地方在于,进程间通信的ID不会随着进程结束自动释放,必须要手动释放。

信号量用于保护不同进程或线程对于有限资源的访问,在进程访问资源前,需要获取信号量,访问结束后释放信号量。当信号量当前值等于0时,获取信号量的进程必须等待,直到有其它进程释放信号量。

XSI Message Queue

消息队列是另一种XSI进程间通信方式,通过两个进程读写同一个内核消息队列来实现进程间通信。

XSI Shared Memory

共享内存是一种最高效的进程间通信方式,直接将一片内存同时映射到两个进程中,然后两个进程读写这片内存即可实现进程间通信。它的代价就是要自己进程同步操作防止出现数据不一致的情况。

POSIX Semaphore

相对于XSI Semaphore,POSIX Semaphore要容易使用的多。

Mutex

一般来说mutex只用于线程间同步,但是通过将一个mutex变量映射到两个不同进程的地址空间中,并设置mutex的进程间共享的属性,也可以用于进程间通信,不过比较麻烦就是啦。如果对于mutex有特殊的爱好,也可以使用的哦。

代码

所有的代码已上传到https://github.com/clpsz/linux-ipcs。虽然每个目录都只有一个main函数,但是代码中使用fork创建了两个进程,不过除了PIPE之外,其它的进程间通信方式并不限于父子进程之间,使用fork只是为了方便测试。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。