版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、进程同步与互斥进程同步与互斥Linux提供以下提供以下3个有关信号量的系统调用函数:个有关信号量的系统调用函数:semget()semop()semctl()下面分别予以引见。下面分别予以引见。1.创建一个新的信号量集或获取一个曾经存在的信号量集创建一个新的信号量集或获取一个曾经存在的信号量集命令格式:命令格式:int semget(key_t key, int nsems, int semflg);前往值:前往值:正确前往:信号量集的标识符正确前往:信号量集的标识符错误前往:错误前往:-11.创建一个新的信号量集或获取一个曾经存在的信号量集创建一个新的信号量集或获取一个曾经存在的信号量集参数
2、阐明:参数阐明:keykey信号量集的信号量集的keykey值:值:运用运用IPC_PRIVATEIPC_PRIVATE,由系统产生,由系统产生keykey值并前往标识符,或者前往值并前往标识符,或者前往keykey值已存在的信值已存在的信号量集的标识符。号量集的标识符。 key key值不为值不为IPC_PRIVATEIPC_PRIVATE而是由用户指定一个非而是由用户指定一个非0 0整型数值,那么对信号量集的翻整型数值,那么对信号量集的翻开或存取操作依赖于开或存取操作依赖于semflagsemflag参数的取值。参数的取值。nsemsnsems指定翻开或者新创建的信号量集将包含的信号量的数
3、目;假设该指定翻开或者新创建的信号量集将包含的信号量的数目;假设该keykey值的信值的信号量集已存在,而号量集已存在,而semflgsemflg只指定了只指定了IPC_CREATIPC_CREAT标志,那么参数标志,那么参数nsemsnsems必需与原来的必需与原来的值一致,否那么也会前往错误信息。该参数最大值在值一致,否那么也会前往错误信息。该参数最大值在linux/sem.hlinux/sem.h中被定义:中被定义:#define SEMMSL 250 /#define SEMMSL 250 /* * = 8 000 = 8 000 * */ /semflgsemflg当当keykey值
4、不为值不为IPC_PRIVATEIPC_PRIVATE:假设只设置假设只设置semflagsemflag的的IPC_CREATIPC_CREAT位,那么创建一个信号量集,假设该信号量集曾位,那么创建一个信号量集,假设该信号量集曾经存在,那么前往其标识符经存在,那么前往其标识符假设设置假设设置semflagsemflag的的IPC_CREAT|IPC_EXCLIPC_CREAT|IPC_EXCL位,那么创建一个新的信号量集,假设位,那么创建一个新的信号量集,假设该该keykey值的信号量集曾经存在那么前往错误信息值的信号量集曾经存在那么前往错误信息只设置只设置IPC_EXCLIPC_EXCL位而
5、不设置位而不设置IPC_CREATIPC_CREAT位没有任何意义。位没有任何意义。1.创建一个新的信号量集或获取一个曾经存在的信号量集创建一个新的信号量集或获取一个曾经存在的信号量集实验中,运用该调用创建一个只含一个信号量的信号量集,格式为:semid=semget(IPC_PRIVATE,1, IPC_CREAT|0666);其中的IPC_PRIVATE可以运用详细的整型数值取代。2.对信号量的对信号量的P、V操作操作命令格式:命令格式:int semop(int semid, struct sembuf * sops, unsigned nsops);前往值:前往值:正确前往:正确前往:
6、0错误前往:错误前往:-1参数阐明:参数阐明:semid信号量集的标识符,由信号量集的标识符,由semget得到。得到。sops指向一个指向一个sembuf构造数组,该数组的每个元素对应一次信构造数组,该数组的每个元素对应一次信号量操作。号量操作。2.对信号量的对信号量的P、V操作操作其其sembufsembuf数据构造如下:数据构造如下:struct sembuf struct sembuf unsigned short sem_num; /unsigned short sem_num; /* * semaphore index in array semaphore index in arr
7、ay * */ /shortshortsem_op;sem_op;/ /* * semaphore operation semaphore operation * */ /shortshortsem_flg;sem_flg;/ /* * operation flags operation flags * */ /;其中的参数含义如下所示:其中的参数含义如下所示:2.对信号量的对信号量的P、V操作操作信号量的信号量的sem_numsem_num值标明它是信号量集的第几个元素,第一个信号量为值标明它是信号量集的第几个元素,第一个信号量为0 0,第二个为,第二个为1 1,依次类推。,依次类推。sem
8、opsemop确定对确定对sem_numsem_num指定的信号量采取何种操作,它可以为负数、正数和零。指定的信号量采取何种操作,它可以为负数、正数和零。假设假设sem_opsem_op为负数:那么相当于为负数:那么相当于P P操作,从信号量的值中减去操作,从信号量的值中减去sem_opsem_op的绝对值:的绝对值: 其差假设大于其差假设大于0 0,那么表示该进程可以运用临界资源进入临界区;,那么表示该进程可以运用临界资源进入临界区; 其差假设小于其差假设小于0 0,在没有指定,在没有指定IPC_NOWAITIPC_NOWAIT的情况下,该进程睡眠,并插入的情况下,该进程睡眠,并插入sem_
9、queuessem_queues等待队列尾部,直到恳求的条件得到满足;假设指定了等待队列尾部,直到恳求的条件得到满足;假设指定了IPC_NOWAITIPC_NOWAIT,那,那么出错前往。么出错前往。假设假设sem_opsem_op为正数:此时相当于为正数:此时相当于V V操作,把它的值加到信号量中,这也意味着该进操作,把它的值加到信号量中,这也意味着该进程释放资源。假设是互斥那么出临界区,释放临界资源。程释放资源。假设是互斥那么出临界区,释放临界资源。假设假设sem_opsem_op为为0 0:那么该进程将睡眠直到信号量的值也为:那么该进程将睡眠直到信号量的值也为0 0。系统会按顺序检查信号
10、量等待队列系统会按顺序检查信号量等待队列(sem_pending)(sem_pending)中的每一个成员,查看在当前信号量中的每一个成员,查看在当前信号量的形状下,其恳求的操作能否可以胜利,假设可以,那么将它从等待队列中唤醒,的形状下,其恳求的操作能否可以胜利,假设可以,那么将它从等待队列中唤醒,并插入到就绪队列中等待调度运转。并插入到就绪队列中等待调度运转。sem_flgsem_flg指明操作的执行方式,它有两个标志位:指明操作的执行方式,它有两个标志位: IPC_NOWAIT IPC_NOWAIT:指明以非阻塞方式:指明以非阻塞方式操作信号量。操作信号量。 SEM_UNDO SEM_UN
11、DO: 指明内核为信号量操作保管恢复值指明内核为信号量操作保管恢复值nsopsnsops是第二个参数所指向的是第二个参数所指向的sembufsembuf构造数组中元素的个数,假设只需一个信号量构造数组中元素的个数,假设只需一个信号量nsopsnsops值为值为1 1。 2.对信号量的对信号量的P、V操作操作在实验中,运用该系统调用实现在实验中,运用该系统调用实现P、V操作,运用格式为:操作,运用格式为:struct sembuf P,V;semop(semid, &P, 1); /对信号量对信号量semid执行执行P操作操作semop(semid, &V, 1); /对信号量对
12、信号量semid执行执行V操作操作3信号量集的控制函数信号量集的控制函数命令格式:命令格式:int semctl(int semid, int semnum, int cmd, union semun arg);前往值:前往值: 操作胜利前往:根据操作胜利前往:根据cmd的不同前往需求的值或的不同前往需求的值或0 错误前往:错误前往:-13信号量集的控制函数信号量集的控制函数参数阐明:参数阐明:semidsemid信号量集的标识符,由信号量集的标识符,由semgetsemget得到;得到;semnumsemnum指定指定semidsemid信号量集的第几个信号量,在吊销信信号量集的第几个信号量
13、,在吊销信号量集时,此参数可以缺省;号量集时,此参数可以缺省;cmdcmd用于指定操作类别:用于指定操作类别: SETVAL SETVAL:置信号量:置信号量semvalsemval域值为域值为arg.valarg.val。 IPC_RMID IPC_RMID:删除指定信号量集。可以进展此项操作:删除指定信号量集。可以进展此项操作的进程限于超级用户、的进程限于超级用户、 sem_perm.cuid sem_perm.cuid或或sem_perm.uidsem_perm.uid。3信号量集的控制函数信号量集的控制函数实验中运用该系统调用实现以下功能:实验中运用该系统调用实现以下功能:为信号量赋初
14、值,格式为:为信号量赋初值,格式为:union semun arg;union semun arg;arg.val=arg.val=初值初值; ; semctl(semid,0semctl(semid,0,SETVAL,arg);SETVAL,arg);其中其中0 0表示第表示第0 0个信号量,个信号量,argarg的值由的值由arg.valarg.val决议,所以必需事先为决议,所以必需事先为arg.valarg.val赋值。赋值。吊销信号量集,格式为:吊销信号量集,格式为:semctl(semid,IPC_RMID,0);semctl(semid,IPC_RMID,0);上述系统调用运用以
15、下头函数:上述系统调用运用以下头函数:#include#include#include#include信号量及其信号量及其P P、V V操作的实现操作的实现信号量及其信号量及其P、V操作的实现方式归纳如下:操作的实现方式归纳如下:1 定义信号量标识符:定义信号量标识符:int semid;假设有假设有n个信号量,那么需求分别定义个信号量,那么需求分别定义n个不同的信号量标识符。个不同的信号量标识符。2 定义信号量数据构造定义信号量数据构造定义定义P、V操作所用的数据构造:操作所用的数据构造:struct sembuf P,V; 定义给信号量赋初值的参数数据构造:定义给信号量赋初值的参数数据构造
16、:union semun arg;3 恳求只需一个信号量的信号量集恳求只需一个信号量的信号量集semid=semget(IPC_PRIVITE,1,IPC_0666);其中,第一个参数:其中,第一个参数:IPC_PRIVATE由系统产生由系统产生key值,也可以由用值,也可以由用户运用详细的整型数值作为户运用详细的整型数值作为key值指定;第二个参数表示信号量值指定;第二个参数表示信号量集中只需一个信号量;操作权限取决于最后一个参数,集中只需一个信号量;操作权限取决于最后一个参数,0666表示表示恣意用户可读可写,只设置恣意用户可读可写,只设置semflag的的IPC_CREAT位,那么创建位
17、,那么创建一个信号量集,假设该信号量集曾经存在,那么前往其标识符。一个信号量集,假设该信号量集曾经存在,那么前往其标识符。4 分别对每个信号量分别对每个信号量semid赋初值赋初值arg.val=初值初值;semctl(semid,0,SETVAL,arg);信号量及其信号量及其P P、V V操作的实现操作的实现5. 定义信号量的定义信号量的P操作供一切信号量的操作供一切信号量的P操作运用操作运用P.sem_num=0;P.sem_op=-1;/*-1表示表示P操作时对信号量减操作时对信号量减1*/P.sem_flg=SEM_UNDO;6. 定义信号量的定义信号量的V操作供一切信号量的操作供一
18、切信号量的V操作运用操作运用V.sem_num=0;V.sem_op=1;/*1表示表示V操作时对信号量加操作时对信号量加1*/V.sem_flg=SEM_UNDO;7. 对信号量对信号量semid执行执行P操作:操作:semop(semid,&P,1);8. 对信号量对信号量semid执行执行V操作:操作:semop(semid,&V,1);9. 吊销信号量:吊销信号量:semctl(semid,IPC_RMID,0);由 于 信 号 量 不 是 普 通 变 量 , 对 它 赋 初 值 只 能 经 过 系 统 调 用 函 数由 于 信 号 量 不 是 普 通 变 量 , 对
19、它 赋 初 值 只 能 经 过 系 统 调 用 函 数semctl(semid,0,SETVAL,arg)进展,其值的修正只能经过进展,其值的修正只能经过P、V操作,而不能操作,而不能运用普通的赋值语句。运用普通的赋值语句。因此其初值和信号量的因此其初值和信号量的P、V操作需求事先定义好以后,然后才干在进程中执行操作需求事先定义好以后,然后才干在进程中执行P、V操作。操作。 运用举例运用举例1.利用信号量实现进程互斥利用信号量实现进程互斥例例4-9 设有父子设有父子2个进程共享一个临界资源,每个进程循环个进程共享一个临界资源,每个进程循环进入该临界区进入该临界区3次:父进程每次进入临界区后显示
20、次:父进程每次进入临界区后显示“prnt in,出临界区那么显示,出临界区那么显示“prnt out;子进程每次进入临;子进程每次进入临界区后显示界区后显示“chld in出临界区那么显示出临界区那么显示“chld out。察。察看运转结果,应该是一个进程出来后另一个才干进去。看运转结果,应该是一个进程出来后另一个才干进去。分析:分析:对临界区设置互斥信号量对临界区设置互斥信号量mutex,其内部标识为,其内部标识为mutexid,初值为初值为1。程序中运用睡眠延时程序中运用睡眠延时1秒来模拟进入临界区前和进入后所执秒来模拟进入临界区前和进入后所执行的程序。行的程序。程序清单:文件名程序清单:
21、文件名sem.c#include#include#include#include#includeint mutexid;/定义信号量标识定义信号量标识int main()int chld,i,j;/*定义数据构造定义数据构造*/struct sembuf P,V;union semun arg;/*创建只含有一个互斥信号量元素的信号量集创建只含有一个互斥信号量元素的信号量集*/mutexid=semget(IPC_PRIVATE,1,0666|IPC_CREAT);/*为信号量赋初值为信号量赋初值*/arg.val=1;if(semctl(mutexid,0,SETVAL,arg)=-1)pe
22、rror(semctl setval error); /*定义定义P、V操作操作*/P.sem_num=0;P.sem_op=-1;P.sem_flg=SEM_UNDO;V.sem_num=0;V.sem_op=1;V.sem_flg=SEM_UNDO;while(chld=fork()=-1); /创建子进程创建子进程if(chld0) /父进程前往父进程前往i=1;while(i=3)/循环循环3次次sleep(1);semop(mutexid,&P,1); /进入临界区前执行进入临界区前执行P操作操作printf(prnt inn);sleep(1);printf(prnt ou
23、tn);semop(mutexid,&V,1); /出临界区执行出临界区执行V操作操作i+;wait(0);/等待子进程终止等待子进程终止semctl(mutexid,IPC_RMID,0);/吊销信号量吊销信号量exit(0);else/子进程前往子进程前往j=1;while(j=3)/循环循环3次次sleep(1);semop(mutexid,&P,1); /进入临界区前执行进入临界区前执行P操作操作printf(chld inn);sleep(1);printf(chld outn);semop(mutexid,&V,1); /出临界区执行出临界区执行V操作操作j
24、+;exit(0);/子进程终止子进程终止编译衔接及运转结果:编译衔接及运转结果:利用信号量实现进程同步利用信号量实现进程同步例例4-10 父进程创建一个子进程,父子进程共享一个存储区,子进程向共享存储父进程创建一个子进程,父子进程共享一个存储区,子进程向共享存储区中以覆盖方式写信息,父进程从该共享存储区中读信息并显示信息。父子区中以覆盖方式写信息,父进程从该共享存储区中读信息并显示信息。父子进程轮番读写,即子进程写一个信息到共享内存中,父进程从中读该信息输进程轮番读写,即子进程写一个信息到共享内存中,父进程从中读该信息输出;然后子进程再写第出;然后子进程再写第2个信息,父进程再读出第个信息,
25、父进程再读出第2个信息输出,如图个信息输出,如图4 6所所示。当信息为示。当信息为“end时读写进程终了。时读写进程终了。父进程父进程子进程子进程单缓冲区单缓冲区图图4 6 单缓冲区同步问题单缓冲区同步问题利用信号量实现进程同步利用信号量实现进程同步同步分析:同步分析:这是一个单缓冲区同步问题,在第这是一个单缓冲区同步问题,在第3章中曾经讨论过这类问题的同步算章中曾经讨论过这类问题的同步算法,读写缓冲区的两个进程之间只需求同步不需求互斥,请参阅法,读写缓冲区的两个进程之间只需求同步不需求互斥,请参阅3.3.6节中的单缓冲区同步问题。节中的单缓冲区同步问题。同步算法:同步算法:子进程执行条件为单
26、缓冲区有空,设信号量子进程执行条件为单缓冲区有空,设信号量empty,初值为,初值为1;父进程执行条件为单缓冲区有数,设信号量父进程执行条件为单缓冲区有数,设信号量full,初值为,初值为0;上述信号量可以由父进程定义、恳求、初始化,然后由父子进程共享运上述信号量可以由父进程定义、恳求、初始化,然后由父子进程共享运用,子进程终了后由父进程吊销。用,子进程终了后由父进程吊销。共享内存设计:共享内存设计:父子进程共享一个内存区,可以由父进程恳求、附接,然后由父子进程父子进程共享一个内存区,可以由父进程恳求、附接,然后由父子进程共享运用,子进程终了后由父进程吊销。共享运用,子进程终了后由父进程吊销。
27、程序清单,文件名为程序清单,文件名为sem2.c:#include#include#include#include#include#include#include/*定义信号量内部标识定义信号量内部标识*/int emptyid;int fullid;main()int chld,i,j;/*定义信号量数据构造定义信号量数据构造*/struct sembuf P,V;union semun arg;/*定义共享内存定义共享内存*/int shmid;char *viraddr;char bufferBUFSIZ; /*创建信号量并初始化创建信号量并初始化*/emptyid=semget(IPC
28、_PRIVATE,1,IPC_CREAT|0666);fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);arg.val=1;if(semctl(emptyid,0,SETVAL,arg)=-1)perror(semctl setval error);arg.val=0;if(semctl(fullid,0,SETVAL,arg)=-1)perror(semctl setval error);/*定义定义P、V操作操作*/P.sem_num=0;P.sem_op=-1;P.sem_flg=SEM_UNDO;V.sem_num=0;V.sem_op=1;V.s
29、em_flg=SEM_UNDO;/*创建并附接共享内存创建并附接共享内存*/shmid=shmget(IPC_PRIVATE,BUFSIZ,0666|IPC_CREAT);viraddr=(char*)shmat(shmid,0,0);while(chld=fork()=-1);/创建子进程创建子进程if(chld0)/父进程前往读信息并输出父进程前往读信息并输出 while(1) semop(fullid,&P,1);/对对fullid执行执行P操作操作printf(Your message is:n%s,viraddr);semop(emptyid,&V,1);/对对emp
30、tyid执行执行V操作操作if(strncmp(viraddr,end,3)=0)break; wait(0);/等待子进程终止等待子进程终止shmdt(viraddr);/断开附接的共享内存断开附接的共享内存shmctl(shmid,IPC_RMID,0);/吊销共享内存和信号量集吊销共享内存和信号量集semctl(emptyid,IPC_RMID,0);semctl(fullid,IPC_RMID,0);printf(Parent ok!n);exit(0);else/子进程前往写信息到共享内存子进程前往写信息到共享内存while(1)semop(emptyid,&P,1);/对对
31、emptyid执行执行P操作操作puts(Enter your text:);fgets(buffer,BUFSIZ,stdin);/键盘输入信息键盘输入信息strcpy(viraddr,buffer); /写信息到共享内存中覆盖方式写信息到共享内存中覆盖方式semop(fullid,&V,1);/对对fullid执行执行V操作操作if(strncmp(viraddr,end,3)=0)sleep(1); /睡眠睡眠1秒,等待父进程将秒,等待父进程将end取走取走break;printf(Child ok!n);exit(0);运转结果:运转结果:由结果可以看出,子进程写到单缓冲区中的
32、信息,父进程都依次取出由结果可以看出,子进程写到单缓冲区中的信息,父进程都依次取出并输出了。并输出了。利用信号量实现进程同步利用信号量实现进程同步例例4-11 设父进程创建一个子进程作为消费者,创建两个子进程作为消设父进程创建一个子进程作为消费者,创建两个子进程作为消费者,这三个子进程运用一个共享内存,该共享内存定义为具有费者,这三个子进程运用一个共享内存,该共享内存定义为具有5个个变量的数组,每个变量表示一个缓冲区,缓冲区号为变量的数组,每个变量表示一个缓冲区,缓冲区号为04。消费者进。消费者进程依次往缓冲区程依次往缓冲区04中写中写10个数据个数据110,两个读进程依次从缓冲区,两个读进程
33、依次从缓冲区04中轮番取出这中轮番取出这10个数据。运用信号量实现进程读写缓冲区的同个数据。运用信号量实现进程读写缓冲区的同步和互斥。步和互斥。消费者消费者同步问题消费者消费者同步问题消费者消费者A进程进程消费者消费者B进程进程消费者进程消费者进程01324利用信号量实现进程同步利用信号量实现进程同步分析:分析:需求创建需求创建3个子进程:消费者、消费者个子进程:消费者、消费者A、消费者、消费者B;需求运用需求运用3个信号量:个信号量:empty、full、mutex,分别表示缓,分别表示缓冲区能否有空、能否有数和互斥信号量,其初值分别为:冲区能否有空、能否有数和互斥信号量,其初值分别为:5,0,1;需求需求2个共享内存:个共享内存:array和和get,分别表示多缓冲区数组
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 九年级上学期语文期末模拟考试试卷
- 售后服务部年终总结
- 一年级数学计算题专项练习集锦
- 二年级数学计算题专项练习1000题汇编
- 《数学物理方法》第1章测试题
- 母鸡孵蛋课件教学课件
- 南京航空航天大学《传感器与检测技术》2021-2022学年第一学期期末试卷
- 南京工业大学浦江学院《土木工程制图》2021-2022学年第一学期期末试卷
- 南京工业大学浦江学院《商务礼仪》2022-2023学年第一学期期末试卷
- 淮河新城二期##楼工程施工组织设计
- 河北省衡水市枣强县2024-2025学年九年级上学期10月月考化学试题
- 航空危险品运输练习题练习试题及答案
- 初二体育与健康(400米跑)教学设计
- 《昔日的世界:地质学家眼中的美洲大陆》札记
- 登革热护理查房
- Unit5HouseworkPartA(课件)闽教版英语六年级上册
- 企业管理学宿恺思考题答案
- 思想政治教学工作计划6篇
- 2024年新人教版一年级语文上册全套试卷
- 2024精麻药品培训知识试题库及答案(完整版)
- 年产5万吨高密度聚乙烯聚合工段基本工艺设计
评论
0/150
提交评论