需求
一个进程(process)可以创建了多个子进程(child processes),而这些子进程又可以创建子子进程,最终,就形成了一个进程树,如下图所示:
这些相关联的子进程可能需要进行相互通讯以同步状态,这就涉及到进程间通信(Interprocess Communication, IPC)。
类似地,进程有时也需要和其他独立的进程进行通信(两个通信的进程没有父子关系)。比如,在 shell 管道(pipeline),一个进程的输出作为另一个进程的输入,这也是进程间通信。
对于线程而言,这也是类似的。因为同一个进程中的线程们共享同一块内存地址空间(address space)。因此,适用于进程间的通信机制当然也适用于线程之间。
进程间通信(Interprocess Communication, IPC)
进程间通信用于实现进程的同步和进程的互斥。
进程的同步与互斥的区别
进程的同步(synchronization)- 进程间的协作
进程的同步(synchronization),是进程之间的具有协作关系,是指系统中多个进程中发生的事件存在某种时序关系,需要相互合作,共同完成一项任务。
具体地说,一个进程运行到某一点时,要求另一个伙伴进程为它提供消息,在未获得消息之前,该进程进入阻塞态,获得消息后被唤醒进入就绪态。
进程的互斥(mutual exclusion)- 进程间的竞争
进程的互斥(mutual exclusion)是指进程之间具有竞争关系,即进程之间在任一时间,只能有一个进程进入临界区(critical regions)。
进程的互斥(mutual exclusion)可以看做是一种特殊的进程同步(synchronization)。
进程间通信方式
进程间通信可以通过以下几种方式:
- 数据传输(Data transfer)
- 管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,联系一个进程的输出和另一个进程的输入。写入在管道的尾部,读出在管道的头部。管道只能传送无格式的字节流。
- 套接字(socket):也是进程间的通信机制,与其它通信机制不同的是,它可以用于不同机器间的进程通信。
- 共享内存(Shared memory)
- 消息通信(Message comunication)
- 消息队列(message queue)
- 操作系统提供的信息通信:send()/receive()
- 信号(Signal)
- 信号量(semaphores)和管程(monitors)
数据传输(Data transfer)
管道(pipe)
管道(pipe),是一种半双工的通信方式,数据只能单向流动,联系一个进程的输出和另一个进程的输入。写入在管道的尾部,读出在管道的头部。管道只能传送无格式的字节流。
在Linux上的管道分两种类型:
- 无名管道 PIPE(可用于父子间进程通信)
- 有名管道 FIFO(可用于任意两个进程间通信)
套接字(socket)
**套接字(socket)**也是进程间的通信机制,与其它通信机制不同的是,它还可以用于不同机器间的进程通信。
共享内存(Shared memory)
**共享内存(Shared memory)**就是映射一段可被其它进程所访问的内存,共享内存由一个进程创建,但是多个进程都可以访问。共享内存是最快的进程间通信方式(IPC),它是针对其它进程通信方式运行效率低的而专门设计的。它往往与其它通信机制。如信号量,配合使用,来实现进程间的同步和通信。
- 在进程间共享内存
- 在线程之间共享内存(全局内存)
消息通信(Message comunication)
消息通信(Message comunication)具体又可细分为以下方式:
- 消息队列(message queue)
- 操作系统提供的信息通信:send()/receive()
- 信号(Signal)
- 锁(Lock)、信号量(semaphores)和管程(monitors)
消息队列(message queue)
早期的 Unix 通信机制一直用的信号能够传送的信息量有限,而管道则只能传送无格式的字节流,且受缓冲区大小限制。消息队列的出现就是为了克服这些缺点。消息队列实质是一个链表(linked list),并把消息看做链表中的每一个记录,具有特定的格式。消息消费后就会被删除。
主要有两种消息队列:
- POSIX 消息队列
- 系统 V 消息队列
方式 2 被广泛应用。系统 V 消息队列是随内核持续的,随人工删除、重启机器则会被删除,要求每个消息队列都在系统范围内对应唯一的键值。
信号(signal)
**信号(signal)**可用于进程间进行异步事件通知。比如在按下某个键、硬件异常(如除数为 0,无效的存储)、进程或用户 kill 函数等从而触发一个事件并且发送一个信号给另一个进程。一个信号的产生叫生成,接收到一个信号叫捕获。Linux 下常见的信号有 SIGKILL、SIGSTOP、SIGALRM 等等。信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
信号量(semaphore)
**信号量(semaphore)**本质是一个计数器,可以用来控制多个进程对共享资源的访问。它也可以作为一种锁的机制,防止某进程正在访问临界区(共享资源)时,其它进程也访问该资源。因此它主要作为进程/线程之间同步的手段。
Reference
-
《Modern Operating System 4th》
-
互斥锁,同步锁,临界区,互斥量,信号量,自旋锁之间联系是什么? - https://www.zhihu.com/question/39850927
-
linux 中进程间6种通信方式 - http://www.syyong.com/linux/6-communication-modes-between-processes-in-Linux.html
-
读写自旋锁详解 - https://www.ibm.com/developerworks/cn/linux/l-cn-rwspinlock1/index.html
-
操作系统原理(Operating Systems) - https://www.coursera.org/learn/os-pku/home/welcome