1、进程间通信

1.1 为什么要进行进程间通信?

  • 每一个进程都有自己独立的进程虚拟地址空间,造成了进程独立性,从而进程间通信技术就是为了各个进程之间可以很好的的交换数据或者进程控制等行为应运而生的。
  • 目前,我们所见到的最大的进程间通信技术:网络

2、进程间通信的目的

  • 数据传输:一个进程需要把它的数据发送给另一个进程
  • 资源共享:多个进程之间共享同样的资源
  • 通知事件:一个进程需要向另一个或一组进程发送消息,通知某时间的发生
  • 进程控制:有些进程希望完全控制另一个进程的执行,此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

3、进程间通信的分类

3.1 管道pipe

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
管道

3.2 命名管道FIFO

有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

3.3 消息队列MessageQueue

消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

消息队列

3.4 共享存储SharedMemory

共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

共享内存

3.5 信号量Semaphore

信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

3.6 套接字Socket

套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

3.7 信号Signal

信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

 

4、信号量

信号量是一个计数器,信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信的数据。

4.1 特点

1)信号量用于进程间同步,若要在进程间传递需要结合共享内存。

2)信号量基于操作系统的PV操作,程序对信号量的操作都是原子操作。

3)每次对信号量的PV操作不仅限于对信号量值加1或减1,而且可以加减任意正整数。

4)支持信号量组。

 

4.2 模型

最简单的信号量是只能取0和1的变量,这也是信号量最常见的一种形式,称为二值信号量。而可以取多个正整数的信号量称为通用信号量。

#include <sys/sem.h>
// 创建或获取一个信号量组:若成功返回信号量集ID,失败返回-1
int semget(key_t key, int num_sems, int sem_flags);
// 对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1
int semop(int semid, struct sembuf semoparray[], size_t numops);  
// 控制信号量的相关信息
int semctl(int semid, int sem_num, int cmd, ...);