【Linux系统编程】进程间通讯--信号量

    在学习信号量之前先来看几个概念:

    临界资源:同一时刻只允许一个进程访问的资源。

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

    原子操作:不可被打断的操作,没有中间状态。

    进程同步:进程间协同工作。

    进程异步:进程间独立运行,互不干扰,需要内核机制来通知。

     在多进程编程中,会存在多个进程同时访问同一个临界资源的情况。比如变量i的初始值为0,进程A和进程B同时执行i++。在执行i++之前,两个进程获得的i值都是0,再执行i++之后,i的值变为1,i++只被执行了一次。而我们想要的结果是进程A和进程B依次执行i++。这就需要信号量来维护进程间的同步。

     信号量是一个特殊的变量。它是一个计数器,大于0时记录当前临界资源的数量,小于等于0时记录等待资源的进程的数量。当信号量的值大于0时,进程总是可以获取到资源并使用;小于等于0时,表示没有临界资源可用,进程必须阻塞等待其他进程释放资源。

     操作方式:对信号量进行操作使用p、v操作。

     p操作:获取资源,信号量的值减1。当信号量的值小于等于0时,此操作会阻塞。

     v操作:释放资源,信号量的值加1。此操作一般情况下不会阻塞。

     p、v操作都是原子操作,i++不是原子操作。一条单独指令的执行才是原子操作。

     p操作的初始值为多少就代表几个资源可以被访问。

 p、v操作力度要小,尽可能只对需要访问的临界资源执行,提高效率。

     API接口:

     #include <sys/sem.h>

     int semget((key_t)key,int nsems,int flag);//创建或获取信号量的内核对象

     int semctl(int semid,int semnum,int cmd,/*union semun arg*/);//设置信号量属性

     int semop(int semid,struct sembuf buff[],int size);//完成对信号量的p操作或v操作

     struct sembuf

     {

           short sem_num;//信号量编号

           short sem_op;//信号量在一次操作中需要改变的数值,p操作为-1,v操作为+1

           short sem_flg;//通常设置为SEM_UNDO

     };

     操作系统对进程间通讯用的信号量在内核中都是以信号量集管理的,即通过semget()函数获取到的是信号量集的标识符。其他函数操作时,必须指明操作的是哪个信号量集中的那个信号量,类似于数组的下标。一个进程创建的信号量,其他进程也可访问。

     命令:

     ipcs -s 查看信号量

     ipcrm -s semid  删除信号量

猜你喜欢

转载自blog.csdn.net/PinkBananA_/article/details/89220331