linux进程间通信方式三:信号量

要理解利用信号量实现进程间通讯的机制,必须先对以下概念有一个大致的了解

       临界资源:同一时刻只能被一个进程访问的资源

       临界区:访问临界资源的代码区

       原子操作:不能被打断的操作,一旦开始执行,只能到其结束,中间不能被打断

       信号量可以用来做进程同步的工具,所谓进程同步,就是多个进程之间的工作有序,协同进行。举例说明:

       A进程要往一个文件里面写入数据,b进程要同步读出a进程在文件中写入的数据。这时如果a进程还没有写入或者正在写入,b进程就开始读取的话,不会读到我们所预期的数据,就说a,b两个进程是异步进行的。而如果当a进程写完之后,b进程才开始读数据,这时b进程就可以正确的读到我们想让他读取的数据。就说两个进程是同步运行的。

       但是b进程如何得知a进程是否已经写完数据呢,这里就会用到我们要说的信号量。

信号量相当于一个临界资源的计数器,我们可以预先定义好临界资源的个数,然后在相应的地方对该信号量所控制的临界资源数量进行加减操作,当我们要运行一个会用到该临界资源的进程时,我们先将临界资源的数量减一,表示我们这个进程使用了一个临界资源。进程结束时,再对该临界资源的数量进行加一操作,表示我们已经用完了这个临界资源。这时如果有其他进程想要使用该临界资源,就执行和该进程相同的加减操作。

       就像停车场里面的车位数量,我们可以把它看成一个临界资源,汽车看作要使用该临界资源的进程,当一辆汽车驶入该停车场时,停车场的车位数量减一,即临界资源数量减一,停车场中停放的车辆驶出停车场时,停车场中的车位数量加一,即临界资源的数量加一。

当停车场只剩最后一个车位时,这时进来一辆车,用光了最后一个临界资源。其他再要使用该停车场的车就只有等待该停车场有车不再使用车位时,它才能使用。

扫描二维码关注公众号,回复: 3731167 查看本文章

 

 

说明了信号量的工作原理,我们再来看信号量的实现机制:

       调用semget系统调用来获取一个内核对象,用户态指定一个key值,内核态会返回给我们一个semid,下次再使用该key值申请内核对象时,我们所获取到的semid是相同的,这就相当于我们在用户态定义了一个文件名,当我们使用open系统调用来操作此文件时,系统会返回给我们一个文件描述符fd一样,相同的文件名返回的fd代表的就是相同的文件,相同的key值,返回的semid操作的就是同一个内核对象。

Nsems参数代表该内核对象中,信号量的个数,flag表示权限。

Semctl系统调用包含了多种信号量的操作

Cmd参数常常被置为下列这几种命令中的一种,作用在semid所指向的信号量上。

函数semop自动执行信号量集合上的操作数组,这是个原子操作

下面是一个例子:我们让a进程写入数据,b进程同步读出数据,使用信号量来控制其同步进行

a.c

b.c

这里的sem文件是这样的

Sem.c

这里sem_p函数就是控制临界资源数量减一的函数,sem_v就是控制临界资源数量加一的函数。

猜你喜欢

转载自blog.csdn.net/Mr_H9527/article/details/83349602