《《进程同步与互斥》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《进程同步与互斥》PPT课件.ppt(31页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、进程同步与互斥进程同步与互斥2/11/20231Linux提供下列提供下列3个有关信号量的系统调用函数:个有关信号量的系统调用函数:semget()semop()semctl()下面分别予以介绍。下面分别予以介绍。2/11/202321.创建一个新的信号量集或获取一个已经存在的信号量集创建一个新的信号量集或获取一个已经存在的信号量集命令格式:命令格式:intsemget(key_tkey,intnsems,intsemflg);返回值:返回值:正确返回:信号量集的标识符正确返回:信号量集的标识符错误返回:错误返回:-12/11/202331.创建一个新的信号量集或获取一个已经存在的信号量集创建
2、一个新的信号量集或获取一个已经存在的信号量集参数说明:参数说明:key信号量集的信号量集的key值:值:使使用用IPC_PRIVATE,由由系系统统产产生生key值值并并返返回回标标识识符符,或或者者返返回回key值值已已存存在在的的信号量集的标识符。信号量集的标识符。key值值不不为为IPC_PRIVATE而而是是由由用用户户指指定定一一个个非非0整整型型数数值值,则则对对信信号号量量集集的的打打开或存取操作依赖于开或存取操作依赖于semflag参数的取值。参数的取值。nsems指指定定打打开开或或者者新新创创建建的的信信号号量量集集将将包包含含的的信信号号量量的的数数目目;如如果果该该ke
3、y值值的的信信号号量量集集已已存存在在,而而semflg只只指指定定了了IPC_CREAT标标志志,那那么么参参数数nsems必必须须与与原来的值一致,否则也会返回错误信息。该参数最大值在原来的值一致,否则也会返回错误信息。该参数最大值在linux/sem.h中被定义:中被定义:#defineSEMMSL250/*=8000*/semflg当当key值不为值不为IPC_PRIVATE:若若只只设设置置semflag的的IPC_CREAT位位,则则创创建建一一个个信信号号量量集集,如如果果该该信信号号量量集集已已经经存在,则返回其标识符存在,则返回其标识符若若设设置置semflag的的IPC_C
4、REAT|IPC_EXCL位位,则则创创建建一一个个新新的的信信号号量量集集,如如果果该该key值的信号量集已经存在则返回错误信息值的信号量集已经存在则返回错误信息只设置只设置IPC_EXCL位而不设置位而不设置IPC_CREAT位没有任何意义。位没有任何意义。2/11/202341.创建一个新的信号量集或获取一个已经存在的信号量集创建一个新的信号量集或获取一个已经存在的信号量集实验中,使用该调用创建一个只含一个信号量的信号量集,格式为:semid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);其中的IPC_PRIVATE可以使用具体的整型数值取代。2/11/202
5、352.对信号量的对信号量的P、V操作操作命令格式:命令格式:intsemop(intsemid,structsembuf*sops,unsignednsops);返回值:返回值:正确返回:正确返回:0错误返回:错误返回:-1参数说明:参数说明:semid信号量集的标识符,由信号量集的标识符,由semget()得到。()得到。sops指指向向一一个个sembuf结结构构数数组组,该该数数组组的的每每个个元元素素对对应应一一次次信信号量操作。号量操作。2/11/202362.对信号量的对信号量的P、V操作操作其其sembuf数据结构如下:数据结构如下:struct sembuf unsigned
6、 short sem_num;/*semaphore index in array*/shortsem_op;/*semaphore operation*/shortsem_flg;/*operation flags*/;其其中的参数含义如下所示:中的参数含义如下所示:2/11/202372.对信号量的对信号量的P、V操作操作信信号号量量的的sem_num值值标标明明它它是是信信号号量量集集的的第第几几个个元元素素,第第一一个个信信号号量量为为0,第第二二个个为为1,依次类推。,依次类推。semop确定对确定对sem_num指定的信号量采取何种操作,它可以为负数、正数和零。指定的信号量采取何种
7、操作,它可以为负数、正数和零。如果如果sem_op为负数:则相当于为负数:则相当于P操作操作,从信号量的值中减去,从信号量的值中减去sem_op的绝对值:的绝对值:其差如果大于其差如果大于0,则表示该进程可以使用临界资源进入临界区;,则表示该进程可以使用临界资源进入临界区;其差如果小于其差如果小于0,在没有指定,在没有指定IPC_NOWAIT的情况下,该进程睡眠,并插入的情况下,该进程睡眠,并插入sem_queues等待队列尾部,直到请求的条件得到满足;如果指定了等待队列尾部,直到请求的条件得到满足;如果指定了IPC_NOWAIT,则出错返回。,则出错返回。如果如果sem_op为正数:此时相当
8、于为正数:此时相当于V操作操作,把它的值加到信号量中,这也意味着该进,把它的值加到信号量中,这也意味着该进程释放资源。如果是互斥则出临界区,释放临界资源。程释放资源。如果是互斥则出临界区,释放临界资源。如果如果sem_op为为0:则该进程将睡眠直到信号量的值也为:则该进程将睡眠直到信号量的值也为0。系统会按顺序检查信号量等待队列系统会按顺序检查信号量等待队列(sem_pending)中的每一个成员,查看在当前信号量中的每一个成员,查看在当前信号量的状态下,其请求的操作是否可以成功,如果可以,则将它从等待队列中唤醒,并的状态下,其请求的操作是否可以成功,如果可以,则将它从等待队列中唤醒,并插入到
9、就绪队列中等待调度运行。插入到就绪队列中等待调度运行。sem_flg指指明明操操作作的的执执行行模模式式,它它有有两两个个标标志志位位:IPC_NOWAIT:指指明明以以非非阻阻塞塞方方式操作信号量。式操作信号量。SEM_UNDO:指明内核为信号量操作保留恢复值指明内核为信号量操作保留恢复值nsops是第二个参数所指向的是第二个参数所指向的sembuf结构数组中元素的个数,结构数组中元素的个数,如果只有一个信号如果只有一个信号量量nsops值值为为1。2/11/202382.对信号量的对信号量的P、V操作操作在实验中,使用该系统调用实现在实验中,使用该系统调用实现P、V操作,使用格式为:操作,
10、使用格式为:structsembufP,V;semop(semid,&P,1);/对信号量对信号量semid执行执行P操作操作semop(semid,&V,1);/对信号量对信号量semid执行执行V操作操作2/11/202393信号量集的控制函数信号量集的控制函数命令格式:命令格式:int semctl(int semid,int semnum,int cmd,unionsemunarg);返回值:返回值:操作成功返回:根据操作成功返回:根据cmd的不同返回需要的值或的不同返回需要的值或0 错误返回:错误返回:-12/11/2023103信号量集的控制函数信号量集的控制函数参数说明:参数说明
11、:semid信号量集的标识符,由信号量集的标识符,由semget()得到;()得到;semnum指指定定semid信信号号量量集集的的第第几几个个信信号号量量,在在撤撤消消信号量集时,此参数可以缺省;信号量集时,此参数可以缺省;cmd用于指定操作类别:用于指定操作类别:SETVAL:置信号量:置信号量semval域值为域值为arg.val。IPC_RMID:删删除除指指定定信信号号量量集集。能能够够进进行行此此项项操操作作的的进程限于超级用户、进程限于超级用户、sem_perm.cuid或或sem_perm.uid。2/11/2023113信号量集的控制函数信号量集的控制函数实验中使用该系统调
12、用实现以下功能:实验中使用该系统调用实现以下功能:为信号量赋初值,格式为:为信号量赋初值,格式为:union semun arg;arg.val=初值初值;semctl(semid,0,SETVAL,arg);其其中中0表表示示第第0个个信信号号量量,arg的的值值由由arg.val决决定定,所所以以必必须须事事先先为为arg.val赋值。赋值。撤消信号量集,格式为:撤消信号量集,格式为:semctl(semid,IPC_RMID,0);上述系统调用使用下列上述系统调用使用下列头函数:头函数:#include#include2/11/202312信号量及其信号量及其P、V操作的实现操作的实现信
13、号量及其信号量及其P、V操作的实现方式归纳如下:操作的实现方式归纳如下:1定义信号量标识符:定义信号量标识符:intsemid;如果有如果有n个信号量,则需要分别定义个信号量,则需要分别定义n个不同的信号量标识符。个不同的信号量标识符。2定义信号量数据结构定义信号量数据结构定义定义P、V操作所用的数据结构:操作所用的数据结构:structsembufP,V;定义给信号量赋初值的参数数据结构:定义给信号量赋初值的参数数据结构:unionsemunarg;3申请只有一个信号量的信号量集申请只有一个信号量的信号量集semid=semget(IPC_PRIVITE,1,IPC_0666);其其中中,第
14、第一一个个参参数数:IPC_PRIVATE由由系系统统产产生生key值值,也也可可以以由由用用户户使使用用具具体体的的整整型型数数值值作作为为key值值指指定定;第第二二个个参参数数表表示示信信号号量量集集中中只只有有一一个个信信号号量量;操操作作权权限限取取决决于于最最后后一一个个参参数数,0666表表示示任任意意用用户户可可读读可可写写,只只设设置置semflag的的IPC_CREAT位位,则则创创建建一一个个信信号号量量集集,如如果果该该信信号号量量集集已已经存在,则返回其标识符。经存在,则返回其标识符。4分别对每个信号量分别对每个信号量semid赋初值赋初值arg.val=初值初值;s
15、emctl(semid,0,SETVAL,arg);2/11/202313信号量及其信号量及其P、V操作的实现操作的实现5.定义信号量的定义信号量的P操作(供所有信号量的操作(供所有信号量的P操作使用)操作使用)P.sem_num=0;P.sem_op=-1;/*-1表示表示P操作时对信号量减操作时对信号量减1*/P.sem_flg=SEM_UNDO;6.定义信号量的定义信号量的V操作(供所有信号量的操作(供所有信号量的V操作使用)操作使用)V.sem_num=0;V.sem_op=1;/*1表示表示V操作时对信号量加操作时对信号量加1*/V.sem_flg=SEM_UNDO;7.对信号量对信
16、号量semid执行执行P操作:操作:semop(semid,&P,1);8.对信号量对信号量semid执行执行V操作:操作:semop(semid,&V,1);9.撤消信号量:撤消信号量:semctl(semid,IPC_RMID,0);因为信号量不是普通变量,对它赋初值只能通过系统调用函数因为信号量不是普通变量,对它赋初值只能通过系统调用函数semctl(semid,0,SETVAL,arg)进行,进行,其值的修改只能通过其值的修改只能通过P、V操作,而不能使操作,而不能使用普通的赋值语句。用普通的赋值语句。因此其初值和信号量的因此其初值和信号量的P、V操作需要事先定义好以后,然后才能在进程
17、中执行操作需要事先定义好以后,然后才能在进程中执行P、V操作。操作。2/11/202314应用举例应用举例1.利用信号量实现进程互斥利用信号量实现进程互斥例例4-9设设有有父父子子2个个进进程程共共享享一一个个临临界界资资源源,每每个个进进程程循循环环进进入入该该临临界界区区3次次:父父进进程程每每次次进进入入临临界界区区后后显显示示“prntin”,出出临临界界区区则则显显示示“prntout”;子子进进程程每每次次进进入入临临界界区区后后显显示示“chldin”出出临临界界区区则则显显示示“chldout”。观观察察运运行行结结果果,应应该该是是一一个个进进程程出出来来后后另另一一个个才才
18、能能进进去。去。分析:分析:对临界区设置互斥信号量对临界区设置互斥信号量mutex,其内部标识为,其内部标识为mutexid,初值为,初值为1。程序中使用睡眠延时程序中使用睡眠延时1秒来模拟进入临界区前和进入后所执行的程序。秒来模拟进入临界区前和进入后所执行的程序。2/11/202315程序清单:文件名程序清单:文件名sem.c#include#include#include#include#includeint mutexid;/定义信号量标识定义信号量标识int main()int chld,i,j;/*定义数据结构定义数据结构*/struct sembuf P,V;union semun
19、 arg;/*创建只含有一个互斥信号量元素的信号量集创建只含有一个互斥信号量元素的信号量集*/mutexid=semget(IPC_PRIVATE,1,0666|IPC_CREAT);/*为信号量赋初值为信号量赋初值*/arg.val=1;if(semctl(mutexid,0,SETVAL,arg)=-1)perror(semctl setval error);2/11/202316 /*定义定义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
20、(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 outn);semop(mutexid,&V,1);/出临界区执行出临界区执行V操作操作i+;wait(0);/等待子进程终止等待子进程终止semctl(mutexid,IPC_RMID,0);/撤消信号量撤消信号量exit(0);2/11/202317else/子进程返回子进程返
21、回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+;exit(0);/子进程终止子进程终止2/11/202318编译连接及运行结果:编译连接及运行结果:2/11/202319利用信号量实现进程同步利用信号量实现进程同步例例4-10父父进进程程创创建建一一个个子子进进程程,父父子子进进程程共共享享一一个个存存储储区区,子子进进程程向向
22、共共享享存存储储区区中中以以覆覆盖盖方方式式写写信信息息,父父进进程程从从该该共共享享存存储储区区中中读读信信息息并并显显示示信信息息。父父子子进进程程轮轮流流读读写写,即即子子进进程程写写一一个个信信息息到到共共享享内内存存中中,父父进进程程从从中中读读该该信信息息输输出出;然然后后子子进进程程再再写写第第2个个信信息息,父父进进程程再再读读出出第第2个个信信息息输输出出,如如图图4 6所所示。当信息为示。当信息为“end”时读写进程结束。时读写进程结束。父进程父进程子进程子进程单缓冲区单缓冲区图图4 6单缓冲区同步问题单缓冲区同步问题2/11/202320利用信号量实现进程同步利用信号量实
23、现进程同步同步分析:同步分析:这这是是一一个个单单缓缓冲冲区区同同步步问问题题,在在第第3章章中中已已经经讨讨论论过过这这类类问问题题的的同同步步算算法法,读读写写缓缓冲冲区区的的两两个个进进程程之之间间只只需需要要同同步步不不需需要要互互斥斥,请请参参阅阅节节中中的的单单缓冲区同步问题缓冲区同步问题。同步算法:同步算法:子进程执行条件为单缓冲区有空,设信号量子进程执行条件为单缓冲区有空,设信号量empty,初值为,初值为1;父进程执行条件为单缓冲区有数,设信号量父进程执行条件为单缓冲区有数,设信号量full,初值为,初值为0;上上述述信信号号量量可可以以由由父父进进程程定定义义、申申请请、初
24、初始始化化,然然后后由由父父子子进进程程共共享享使使用,子进程结束后由父进程撤消。用,子进程结束后由父进程撤消。共享内存设计:共享内存设计:父父子子进进程程共共享享一一个个内内存存区区,可可以以由由父父进进程程申申请请、附附接接,然然后后由由父父子子进进程程共享使用,子进程结束后由父进程撤消。共享使用,子进程结束后由父进程撤消。2/11/202321程序清单,文件名为程序清单,文件名为sem2.c:#include#include#include#include#include#include#include/*定义信号量内部标识定义信号量内部标识*/int emptyid;int fulli
25、d;main()int chld,i,j;/*定义信号量数据结构定义信号量数据结构*/struct sembuf P,V;union semun arg;/*定义共享内存定义共享内存*/int shmid;char*viraddr;char bufferBUFSIZ;2/11/202322 /*创建信号量并初始化创建信号量并初始化*/emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);arg.val=1;if(semctl(emptyid,0,SETVAL,arg)=-
26、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.sem_flg=SEM_UNDO;/*创建并附接共享内存创建并附接共享内存*/shmid=shmget(IPC_PRIVATE,BUFSIZ,0666|IPC_CREAT);viraddr=(char*)shmat(shmid,0
27、,0);2/11/202323while(chld=fork()=-1);/创建子进程创建子进程if(chld0)/父进程返回读信息并输出父进程返回读信息并输出while(1)semop(fullid,&P,1);/对对fullid执行执行P操作操作printf(Yourmessageis:n%s,viraddr);semop(emptyid,&V,1);/对对emptyid执行执行V操作操作if(strncmp(viraddr,end,3)=0)break;wait(0);/等待子进程终止等待子进程终止shmdt(viraddr);/断开附接的共享内存断开附接的共享内存shmctl(shmi
28、d,IPC_RMID,0);/撤消共享内存和信号量集撤消共享内存和信号量集semctl(emptyid,IPC_RMID,0);semctl(fullid,IPC_RMID,0);printf(Parentok!n);exit(0);2/11/202324else/子进程返回写信息到共享内存子进程返回写信息到共享内存while(1)semop(emptyid,&P,1);/对对emptyid执行执行P操作操作puts(Enteryourtext:);fgets(buffer,BUFSIZ,stdin);/键盘输入信息键盘输入信息strcpy(viraddr,buffer);/写信息到共享内存中
29、(覆盖方式)写信息到共享内存中(覆盖方式)semop(fullid,&V,1);/对对fullid执行执行V操作操作if(strncmp(viraddr,end,3)=0)sleep(1);/睡眠睡眠1秒,等待父进程将秒,等待父进程将end取走取走break;printf(Childok!n);exit(0);2/11/202325运行结果:运行结果:由由结结果果可可以以看看出出,子子进进程程写写到到单单缓缓冲冲区区中中的的信信息息,父父进进程程都都依依次次取取出出并并输出了。输出了。2/11/202326利用信号量实现进程同步利用信号量实现进程同步例例4-11设设父父进进程程创创建建一一个个
30、子子进进程程作作为为生生产产者者,创创建建两两个个子子进进程程作作为为消消费费者者,这这三三个个子子进进程程使使用用一一个个共共享享内内存存,该该共共享享内内存存定定义义为为具具有有5个个变变量量的的数数组组,每每个个变变量量表表示示一一个个缓缓冲冲区区,缓缓冲冲区区号号为为04。生生产产者者进进程程依依次次往往缓缓冲冲区区04中中写写10个个数数据据110,两两个个读读进进程程依依次次从从缓缓冲冲区区04中中轮轮流流取取出出这这10个个数数据据。使使用用信信号号量量实实现现进进程程读读写写缓缓冲冲区区的的同同步步和互斥。和互斥。生产者消费者同步问题生产者消费者同步问题消费者消费者A进程进程消
31、费者消费者B进程进程生产者进程生产者进程013242/11/202327利用信号量实现进程同步利用信号量实现进程同步分析:分析:需要创建需要创建3个子进程:生产者、消费者个子进程:生产者、消费者A、消费者、消费者B;需需要要使使用用3个个信信号号量量:empty、full、mutex,分分别别表表示示缓缓冲冲区区是是否否有有空空、是是否否有有数数和和互互斥斥信信号号量量,其其初初值值分分别别为为:5,0,1;需需要要2个个共共享享内内存存:array和和get,分分别别表表示示多多缓缓冲冲区区数数组组变变量量array04、和和消消费费者者读读缓缓冲冲区区号号的的计计数数get,get计计数数
32、由由两两个个消消费费者者进进程程共共享享,由由于于生生产产者者只只有有一一个个没没,所所以写缓冲区号的计数以写缓冲区号的计数set不需要使用共享内存。不需要使用共享内存。2/11/202328算法:算法:创建共享存储区创建共享存储区array,get;附接共享存储区到进程空间;附接共享存储区到进程空间;共享存储区赋初值;共享存储区赋初值;创建信号量创建信号量empty并初始化;并初始化;创建信号量创建信号量full并初始化;并初始化;创建信号量创建信号量mutex并初始化;并初始化;创建生产者子进程;创建生产者子进程;如果生产者子进程返回:如果生产者子进程返回:for(i=0;i10,i+)P
33、(empty);P(mutex););写数据到共享存储区;写数据到共享存储区;缓冲区计数缓冲区计数set+;V(mutex););V(full);exit(0);如果父进程返回:如果父进程返回:创建消费者创建消费者A子进程;子进程;如果消费者如果消费者A进程返回:进程返回:for(i=0;i10,i+)P(full);P(mutex););从共享存储区中取数据;从共享存储区中取数据;缓冲区计数缓冲区计数(*get)+;V(mutex););V(empty);exit(0);如果父进程返回:如果父进程返回:创建消费者创建消费者B子进程;子进程;如果消费者如果消费者B进程返回:进程返回:2/11/
34、202329算法:算法:for(i=0;i10,i+)P(full);P(mutex););从共享存储区中取数据;从共享存储区中取数据;缓冲区计数缓冲区计数(*get)+;V(mutex););V(empty);exit(0);程序清单:程序清单:semshm.doc如果父进程返回:如果父进程返回:wait(0);wait(0);wait(0);断开断开2个共享存储区;个共享存储区;撤消撤消2个共享存储区;个共享存储区;撤消撤消3个信号量;个信号量;exit(0);2/11/202330编译连接并执行后的输出结果如下:编译连接并执行后的输出结果如下:由由运运行行结结果果可可以以看看出出,生生产产者者进进程程分分别别往往缓缓冲冲区区04中中送送了了10次次产产品品,消消费费者者进进程程A和和B轮轮流流从从缓缓冲冲区区04中中取取走走产产品品,并并实实现现了了3个个进进程程之之间间的的同同步步和和互互斥斥,即即实实现现了了生生产产者者进进程程送送了了产产品品后后消消费费者者进进程程才才取取走走产品,并且一次只有一个进程进入缓冲区。产品,并且一次只有一个进程进入缓冲区。2/11/202331