资源描述:
《进程共享资源信号量控制详细实现(源码附解释)》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、信号量信号量(Semaphore)简单地说就是用来控制多个进程对共享资源使用地计数器.它是常被用作一种锁定保护机制,当某个进程对资源进行操作时阻止其他进程对该资源地访问.需要注意地是,SystemV中地地信号量对象实际上是信号量地集合(set),它可以包含多个信号量,控制多个共享资源.有关地数据结构和消息队列一样,我们在介绍他地使用前先介绍一些相关地数据结构:1.sem前提提到,信号量对象实际是多个信号量地集合.在Linux系统中,这种集合是以数组地形式实现地.数组地每个成员都是一个单独地信号量,它们在系统中是以sem结构地形式存储地.Sem地结构在Linux系统linux/sem.h中定义是
2、这样地:/*Onesemaphorestructureforeachsemaphoreinthesystem.*/Structsem{Shortsempid;/*pidoflastoperation*/Ushortsemval;/*currentvalue*/Ushortsemncnt;/*numprocsawaitingincreaseinsemval*/Ushortsemzcnt;/*numprocsawaitingsemval=0*/};其中,Sem_pid成员保存了最近一次操作信号量进程地pid.Sem_semval成员保存着信号量地计数值.Sem_semncnt成员保存着等待使用资源
3、地进程数目.Sem_semzcnt成员保存等待资源完全空闲地进程数目.2.semunSemun联合在senctl()函数中使用,提供senctl()操作所需要地信息.它在Linux系统linux/sem.h中定义是这样地:/*argforsemctlsystemcalls*/Unionsemun{Intval;/*valueforSETVAL*/Structsemid_ds*buf;/*bufferforIPC_STAT&SETALL*/Ushort*array;/*arrayforGETALL&SETALL*/Structseminfo*__buf;/*bufferforIPC_INFO*/
4、Void*_pad;};前三个参数在对senctl()函数介绍中会讲到,这里暂时先不管它们.后两个参数是Linux系统所独有地,只是系统地内核中使用.3.semufsemuf结构被semop()函数(后面会讲到)用来定义对信号量对象地基本操作.它在linux/sem.h中是这样定义地:/*semopsystemcallstakesanarrayofthese.*/Stcuctsembuf{Unsignedshortsem_num;/*semaphoreindexinarray*/Shortsem_op;/*semaphoreoperation*/Shortsem_flg;/*operation
5、flags*/};其中,Sem_num成员为接受操作地信号量在信号量数组中地序号(数组下标).Sem_op成员定义了进行地操作(可以是正,负和零).Sem_flg是控制操作行为地标志.如果sem_op是负值,就从指定地信号量中减去相应地值.这对应着获取信号量所监控地资源操作.如果没有sem_flg指定IPC_NOWAIT标志,那么,当现有地信号量数值小于sem_op地绝对值(表示现有地资源少于要获取地资源)时,调用semop()_函数地进程就会被阻塞知道信号量地数值大于sem_op地绝对值(表示有足够地资源被释放).如果sem_op是正值,就在指定地信号量中加上相应地值.这对应着释放信号量所监
6、控地资源操作.如果sem_op是零,那么调用semop()函数地进程就会被阻塞到直对应地信号量值为零.这种操作地实质就是等待信号量所监控地资源被全部使用.利用这种资源操作可以动态监控资源地使用并调整资源地分配,避免不必要地等待.4.Semid_qs和msgqid_ds类似,semid_qs结构被系统用来存储每个信号量对象地有关信息.它在Linux系统库linux/sem.h中是这样定义地:/*Onesemiddatastructureforeachsetofsemaphoresinthesystem*/Structsemid_ds{Structipc_permsem_perm;/*permis
7、sions..seeipc.h*/__kernel_time_tsem_otime;/*tastsemoptime*/__kernel_time_tsem_ctime;/*lastchangetime*/Structsem*sem_base;/*ptrtofirstsemaphoreinarray*/Structsem_queue*sem_pending;/*pendingoprationstob