目录
消息队列(message queue)
信号量(Semaphore)
system V版本的进程间通信方式有三种:共享内存,消息队列和信号量。之前我们已经说了共享内存,那么我们来看一下消息队列和信号量以及它们之间都属于一个版本,所以不管是接口还是底层实现都有很多的相似性,我们也一同来探讨一下。
消息队列(message queue)
所谓的消息队列就是在内核中维护着一个队列,进程A和进程B之间要进行通信就把自己要发送的信息放到这个队列中,为了区分是哪个进程发的,信息要有类型,其实就是用一个标记位标记一下。用简单的图来表示就是这样:
那么下面我们就来介绍一下它的接口
man msgget用来创建消息队列
我们可以看到它的参数和shmget 的参数是一样的,所以key也是由ftok生成,msgflg也是传选项IPC_CREAT和IPC_EXCL,这和共享内存是一样的。
man msgctl用来控制消息队列,包括删除
这个函数也是跟shmctl是完全一样的,第二个参数就是选项,第三个参数也是内核暴露给我们的信息:
这个跟共享内存也是完全一样的,都是这样的结构
下一个接口就是进程像消息队列发送和接收消息的接口
msgsnd msgrcv
这里的msgp就是要传OS给我们提供的一个结构体类型创建的对象
信号量(Semaphore)
首先,我们需要知道几个名词并明白它们的意义,
互斥:就是在访问一部分共享资源的时候,任何时候都只有我一人访问,就叫做互斥
同步:就是访问资源在安全的前提下,具有一定的顺序性
被保护起来的,任何时刻只能有一个进程访问的叫临界资源
访问临界资源的代码,叫做临界区,当然了这个之外的就叫做非临界区
原子性:操作对象的时候只有两种状态,要么还没开始,要么已经结束
其实信号量本质就是一个计数器,描述临界资源数量的这样一个计数器,用来控制访问该资源的进程数量。
当我们申请资源的时候这个计数器就会--,当释放资源的时候这个计数器就会++,前者也被称为P操作,后者也被称为V操作。
那么下面我们就来认识一些信号量的接口
man semget
第二个参数是你想创建几个信号量,就是几个计数器,所以这个函数返回的是信号量集标识符
man semctl
信号量的内核暴露给我们的信息跟消息队列和共享内存几乎一样的
man semop进行PV操作
第二个参数就是我们通过这个结构体传要进行什么操作
我们可以看到,system V版本的三种进程间通信的方式它们的相似之处还是有很多的,就比如:它们的有关信息的结构体:shmid_ds,msgid_ds,semid_ds,它们三个结构中第一个成员都是ipc_perm,于是我们就可以用一个数组把三种方式管理起来,数组中存放ipc_perm的指针,ipc_perm结构体中存着它是哪一种通信方式。这样只要知道了ipc_perm的指针以及是那种通信方式,我们就可以获取到这种通信方式的信息。
通过这样的方式,就把三种进程间通信方式管理到了同一个数组中