一个多值信号量量的初值设为>1的值,有什么好处

信号量的初值设为2时(反正就是大于1),信号量怎么运作?在1965年提出的一种解决同步、互斥问题的较通用的方法,并在很多操作系统中得以实现, Linux改进并实现了这种机制。
实际是一个整数,它的值由多个进程进行测试(test)和设置(set)。就每个进程所关心的测试和设置操作而言,这两个操作是不可中断的,或称“原子”操作,即一旦开始直到两个操作全部完成。测试和设置操作的结果是:信号量的当前值和设置值相加,其和或者是正或者为负。根据测试和设置操作的结果,一个进程可能必须睡眠,直到有另一个进程改变信号量的值。
的信号量,在这个信号量上实施两个操作,首先测试并且给信号量的值减1,然后测试并给信号量的值加1。当第一个进程存取文件时,它把信号量的值减1,并获得成功,信号量的值现在变为0,这个进程可以继续执行并存取数据文件。但是,如果另外一个进程也希望存取这个文件,那么它也把信号量的值减1,结果是不能存取这个文件,因为信号量的值变为-1。这个进程将被挂起,直到第一个进程完成对数据文件的存取。当第一个进程完成对数据文件的存取,它将增加信号量的值,使它重新变为1,现在,等待的进程被唤醒,它对信号量的减1操作将获得成功。
。实际上,信号量作为资源计数器,它的初值可以是任何正整数,其初值不一定为0或1。另外,如果一个进程要先获得两个或多个的共享资源后才能执行的话,那么,相应地也需要多个信号量,而多个进程要分别获得多个临界资源后方能运行,这就是信号量集合机制,Linux 讨论的就是信号量集合问题。
存在于include/linux/sem.h中),其它一些数据结构将在相关的系统调用中介绍。
int& &&&&&&&&
int&& &&&&&&&&
的数据结构(semid_ds)
struct ipc_perm sem_&&&&&&&&&
& long&&&&&&&
sem_ &&&&&&&/* 的时间 */
long&&&&&&&
sem_&&&&&&& /*
struct sem&&&&& *sem_&&&&& /*
sem_queue *sem_&&&&&& /*
struct sem_queue **sem_pending_ /*
struct sem_undo * &&&&&&&&
/* 请求 */
ushort&&&&&&&&&
sem_&&&&&&&&&&
struct sem_queue * && /*
struct sem_queue **&&& &&
struct wait_queue *&&& &&& /*
struct sem_undo *& &&
int&&& &&&&&&& &&&
int&&& &&&&&&&
struct semid_ds *& &&&
struct sembuf *&&& &&
图可以看出,semid_ds结构的sem_base指向一个信号量数组,允许操作这些信号量集合的进程可以利用系统调用执行操作
。注意,信号量信号量集合的区别,从上面可以看出,信号量用“sem”结构描述,实际上,在后面的讨论中,我们以信号量集合为讨论的主要对象。下面我们给出这几个结构之间的关系,如图7.3所示。
&System V IPC信号量数据结构之间的关系
系统调用,其描述如下:
( key_t key, int nsems, int semflg );&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
如果成功,则返回信号量集合的IPC识别号
,则出现错误:
这个键值要与已有的键值进行比较,已有的键值指在内核中已存在的其它信号量集合的键值。对信号量集合的打开或存取操作依赖于semflg参数的取值:
一起使用时,但信号量集合已经存在,则创建失败。
单独使用,semget()为一个新创建的集合返回标识号,或者返回具有相同键值的已存在集合的标识号。如果IPC_EXCL与IPC_CREAT一起使用,要么创建一个新的集合,要么对已存在的集合返回-1。IPC_EXCL单独是没有用的,当与IPC_CREAT结合起来使用时,可以保证新创建集合的打开和存取。
的其它形式,一种可选项是把一个八进制与掩码或,形成信号量集合的存取权限。
指的是在新创建的集合中信号量的个数。其最大值在“linux/sem.h”
&&&#define SEMMSL& 250&&&&&&&&&&&&
/* &= 8 000 max num of semaphores per id */
参数可以忽略。
if ( ! numsems )
return(-1);
if((sid = semget( keyval, numsems, IPC_CREAT | 0660 )) ==
return(-1);
return(sid);
权限。这个函数要么返回一个集合的标识号,要么返回-1而出错。键值必须传递给它,信号量的个数也传递给它,这是因为如果创建成功则要分配空间。
int semid, struct sembuf *sops, unsigned nsops);
如果所有的操作都执行,则成功返回0。
,则出错。&&&&&&&&
是集合的识别号(可以由semget()系统调用得到)。第二个参数(sops)是一个指针,它指向在集合上执行操作的数组。而第三个参数(nsop)是在那个数组上操作的个数。
的一个数组,这个结构在/inclide/linux/sem.h 中声明,是内核中的一个数据结构,描述如下:
struct sembuf {
ushort& sem_&&&&&&& /*
short&& sem_&&&&&&&&
/* 正数、负数或0) */
short&& sem_&&&&&&& /* 或SEM_UNDO*/
为负数,那么就从信号量的值中减去sem_op的绝对值,这意味着进程要获取资源,这些资源是由信号量控制或监控来存取的。如果没有指定IPC_NOWAIT,那么调用进程睡眠到请求的资源数得到满足(其它的进程可能释放一些资源)。
是正数,把它的值加到信号量,这意味着把资源归还给应用程序的集合。
为0,那么调用进程将睡眠到信号量的值也为0,这相当于一个信号量到达了100%的利用。
按如下的规则判断是否所有的操作都可以成功:操作值和信号量的当前值相加大于 0,或操作值和当前值均为 0,则操作成功。如果系统调用中指定的所有操作中有一个操作不能成功时,则 Linux 会挂起这一进程。但是,如果操作标志指定这种情况下不能挂起进程的话,系统调用返回并指明信号量上的操作没有成功,而进程可以继续执行。如果进程被挂起,Linux 必须保存信号量的操作状态并将当前进程放入等待队列。为此,Linux 内核在堆栈中建立一个 sem_queue 结构并填充该结构。新的 sem_queue 结构添加到集合的等待队列中(利用 sem_pending 和 sem_pending_last 指针)。当前进程放入 sem_queue 结构的等待队列中(sleeper)后调用调度程序选择其他的进程运行。
调用,让我们来看一个例子。假设我们有一台打印机,一次只能打印一个作业。我们创建一个只有一个信号量的集合(仅一个打印机),并且给信号量的初值为1(因为一次只能有一个作业)。
数组来执行这个操作:
表示集合中信号量数组的索引,即在集合中只有一个信号量,-1表示信号量操作(sem_op),操作标志为IPC_NOWAIT,表示或者调用进程不用等待可立即执行,或者失败(另一个进程正在打印)。下面是用初始化的sembuf结构进行semop()系统调用的例子:
if((semop(sid, &sem_lock, 1) == -1)
fprintf(stderr,&semop\n&);
是说我们仅仅执行了一个操作(在我们的操作数组中只有一个sembuf结构),sid参数是我们集合的IPC识别号。
struct sembuf sem_unlock = { 0, 1, IPC_NOWAIT };
加到集合数组的第0个元素,换句话说,一个单位资源返回给集合。
( int semid, int semnum, int cmd, union semun arg );
成功返回正数,出错返回-1。
是在集合上执行控制操作。
是集合的标识号,第二个参数(semnn)是将要操作的信号量个数,从本质上说,它是集合的一个索引,对于集合上的第一个信号量,则该值为0。
参数表示在集合上执行的命令,这些命令及解释如表7.2所示:
参数的类型为semun,这个特殊的联合体在 include/linux/sem.h中声明,对它的描述如下:
arg for semctl system calls. */
union semun {
&&&&&&&&&&&int&&&&&&&&&&&&&&&
/* value for SETVAL */
struct semid_ds *&& /* buffer for IPC_STAT &
IPC_SET */
ushort *&&&&&&&&&
/* array for GETALL & SETALL */
struct seminfo *__& /* buffer for IPC_INFO */
& cmd命令及解释
-1中提到,剩下的两个成员_buf 和_pad用在内核中信号量的实现代码,开发者很少用到。事实上,这两个成员是Linux操作系统所特有的,在UINX中没有。
对应信号量的值。当用GETVAL命令时,最后的参数(semnum)被忽略。
return( semctl(sid, semnum, GETVAL, 0));
系统调用,相对要简单地多,也深入地多。
而没有退出临界区,这时,其他被挂起在信号量上的进程永远得不到运行机会,这就是所谓的死锁。Linux 通过维护一个信号量数组的调整列表(semadj)来避免这一问题。其基本思想是,当应用这些“调整”时,让信号量的状态退回到操作实施前的状态。
数据结构中,在include/linux/sem.h描述如下:
请求,当进程退出时,自动执行undo请求*/
struct sem_undo *&
proc_& /*节点 */
struct sem_undo *& id_&& & /* 节点*/
&&&&&&&&&&&&&&
short *&&& &&&&&& & &
数据结构中。
将为每一个信号量数组的每一个进程维护至少一个sem_undo结构。如果请求的进程没有这个结构,当必要时则创建它,新创建的sem_undo数据结构既在这个进程的task_struct数据结构中排队,也在信号量数组的semid_ds结构中排队。当对信号量数组上的一个信号量施加操作时,这个操作值的负数与这个信号量的“调整”相加,因此,如果操作值为2,则把-2加到这个信号量的“调整”域。
完成了对sem_undo数据结构的设置及对信号量数组的调整。如果一个信号量集合被删除,sem_undo结构依然留在这个进程的task_struct结构中,但信号量集合的识别号变为无效。操作系统 PV深度剖析
PV操作的例题38
上亿文档资料,等你来发现
操作系统 PV深度剖析
PV操作的例题38
PV操作的例题;一、线程是进程的一个组成部分,一个进程可以有多个;二、在计算机操作系统中,PV操作是进程管理中的难;PV操作的意义:我们用信号量及PV操作来实现进程;什么是信号量?信号量(semaphore)的数据;利用信号量和PV操作实现进程互斥的一般模型是:进;其中信号量S用于互斥,初值为1;(1)每个程序中用户实现互斥的P、V操作必须成对;(2)P、V
PV操作的例题一、线程是进程的一个组成部分,一个进程可以有多个线程,而且至少有一个可执行线程。进程的多个线程都在进程的地址空间内活动。 资源是分给进程的,而不是分给线程的,线程需要资源时,系统从进程的资源配额中扣除并分配给它。处理机调度的基本单位是线程,线程之间竞争处理机,真正在处理机上运行的是线程。线程在执行过程中,需要同步。二、在计算机操作系统中,PV操作是进程管理中的难点。 首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:
P(S):①将信号量S的值减1,即S=S-1;
②如果S&=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
V(S):①将信号量S的值加1,即S=S+1;
②如果S&0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。 什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。
一般来说,信号量S&=0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减1;当S&0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S的值加1;若S?0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。利用信号量和PV操作实现进程互斥的一般模型是: 进程P1
进程Pn ……
…… P(S);
P(S); 临界区;
临界区; V(S);
V(S); ……
……其中信号量S用于互斥,初值为1。
使用PV操作实现进程互斥时应该注意的是:(1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。(2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。(3)互斥信号量的初值一般为1。利用信号量和PV操作实现进程同步 PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。
使用PV操作实现进程同步时应该注意的是:(1)分析进程间的制约关系,确定信号量种类。在保持进程间有正确的同步关系情况下,哪个进程先执行,哪些进程后执行,彼此间通过什么资源(信号量)进行协调,从而明确要设置哪些信号量,即有多少同步信号量,有多少互斥信号量(初始值为1)。(2)同步信号量的初值与相应资源的数量有关,也与P、V操作在程序代码中出现的位置有关。(3)同一信号量的P、V操作要成对出现,但它们分别在不同的进程代码中。例题一:过桥问题解:设信号量初值S=1
汽车进程Pi(i=1,2,3,…)
P(s) V(s)到桥达桥行另一驶 端例题二若有一售票厅只能容纳300人,当少于300人时,可以进入。否则,需在外等候, 若将每一个购票者作为一个进程,请用P、V操作编程。解:信号量初值S=300
购票者进程Pi(i=1,2,3,…)
P(s) 进退入购出售票售票厅 票 厅 V(s)例题三有一只铁笼子,每次只能放入一只动物,猎手向笼中放入老虎,农民向笼中放入猪,动物园等待取笼中的老虎,饭店等待取笼中的猪,试用P、V操作写出能同步执行的程序。解:两个生产者和两个消费者共享了一个仅能存放一件产品的缓冲器,生产者各自生产不同的产品,消费者各自取自己需要的产品,P、V操作编程为:猎手进程
动物园进程
V(s) 其中S初值=1,S1=S2=0例题四桌上有一只盘子,每次只能放入一个水果。爸爸专向盘中放苹果,妈妈专向盘中放桔子,女儿专等吃盘中的苹果,儿子专等吃盘中的桔子。用P、V操作写出它们能正确同步的程序。(同例六详解)解:信号量初值S1=0,S2=0,S=1
repeatP(s)
P(s)取苹P(s1)
取桔P(s2) 子 V(s)
V(s2)until false
until false
until false
until false例题五
设有两个优先级相同的进程P1和P2如下,S1和S2初值均为0,求:P1,P2并发执行结束后,x,y,z分别是多少?
z:=x+z;解:因为P1、P2是并发进程,所以P1和P2调度顺序不确定。假设P1先执行,当P1执行到P(s2)时,s2=-1,P1阻塞,此时y=3,z=4;当调度程序调度到P2时,由于进程P1巳执行到了V(s1),P2在执行P(s1)时,不阻塞而继续执行,当执行到V(s2)时,将P1唤醒,然后执行到最后一个语句,此时x=5,z=9;当P1再次被唤醒、调度时,继续执行P1的最后一处语句,此时y=12.所以最后结果是:x=5,y=12,z=9.如果P2先执行,结果同上 【例题五】生产者-消费者问题 在多道程序环境下,进程同步是一个十分重要又令人感兴趣的问题,而生产者-消费者问题是其中一个有代表性的进程同步问题。下面我们给出了各种情况下的生产者-消费者问题,深入地分析和透彻地理解这个例子,对于全面解决操作系统内的同步、互斥问题将有很大帮助。(1)一个生产者,一个消费者,公用一个缓冲区。 定义两个同步信号量: empty――表示缓冲区是否为空,初值为1。
full――表示缓冲区中是否为满,初值为0。 生产者进程 while(TRUE){生产一个产品;
V(full); }消费者进程 while(True){P(full);从Buffer取出一个产品;
消费该产品;
}(2)一个生产者,一个消费者,公用n个环形缓冲区。定义两个同步信号量: empty――表示缓冲区是否为空,初值为n。 full――表示缓冲区中是否为满,初值为0。设缓冲区的编号为1~n-1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针 ,指向下一个可用的缓冲区。 生产者进程 while(TRUE){ } 产生品产一个buffer产(nin品; P(empty); ); ; V(full);程 送往in=(in+1)mod 消while(TRUE){P(full); 从buffer费者进(out)out=(out+1)mod 费该中取n产出产品; ; V(empty); ; } 消品(3)一组生产者,一组消费者,公用n个环形缓冲区
在这个问题中,不仅生产者与消费者之间要同步,而且各个生产者之间、各个消费者之间还必须互斥地访问缓冲区。 定义四个信号量: empty――表示缓冲区是否为空,初值为n。 full――表示缓冲区中是否为满,初值为0。 mutex1――生产者之间的互斥信号量,初值为1。 mutex2――消费者之间的互斥信号量,初值为1。设缓冲区的编号为1~n-1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。 生产者进程 while(TRUE){生产一个产品;
P(mutex1);
产品送往buffer(in);
in=(in+1)mod n;
V(mutex1);
V(full); }消费者进程 while(TRUE){P(full) 从bufferV消P(mutex2)(out)中取out=(out+1)mod (mutex2费该产出n)品产; 品; ; ; V(empty); ; }
需要注意的是无论在生产者进程中还是在消费者进程中,两个P操作的次序不能颠倒。应先执行同步信号量的P操作,然后再执行互斥信号量的P操作,否则可能造成进程死锁。【例题六】桌上有一空盘,允许存放一只水果。爸爸可向盘中放苹果,也可向盘中放桔子,儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时一次只能放一只水果供吃者取用,请用P、V原语实现爸爸、儿子、女儿三个并发进程的同步。分析在本题中,爸爸、儿子、女儿共用一个盘子,盘中一次只能放一个水果。当盘子为空时,爸爸可将一个水果放入果盘中。若放入果盘中的是桔子,则允许儿子吃,女儿必须等待;若放入果盘中的是苹果,则允许女儿吃,儿子必须等待。本题实际上是生产者-消费者问题的一种变形。这里,生产者放入缓冲区的产品有两类,消费者也有两类,每类消费者只消费其中固定的一类产品。解:在本题中,应设置三个信号量S、So、Sa,信号量S表示盘子是否为空,其初值为l;信号量So表示盘中是否有桔子,其初值为0;信号量Sa表示盘中是否有苹果,其初值为0。同步描述如下: int S=1; int Sa=0; int So=0;
daughter();
将水果放入盘中;
if(放入的是桔子)V(So);
{包含各类专业文献、行业资料、专业论文、高等教育、幼儿教育、小学教育、外语学习资料、文学作品欣赏、操作系统 PV深度剖析
PV操作的例题38等内容。 
 操作系统PV操作习题_工学_高等教育_教育专区。一、用 P、V 操作描述前趋关系。P1、P2、P3、P4、P5、 P6 为一组合作进程,其前趋图如图 2.3 所示,试用 P、...  计算机操作系统PV操作例题_理学_高等教育_教育专区。问题 1 一个司机与售票员的例子 在公共汽车上,为保证乘客的安全,司机和售票员应协调工作: 停车后才能开门,关...  信号量的PV操作(例题)_工学_高等教育_教育专区。操作系统有关信号量PV操作的部分知识,含有例题。???信号量的 PV 操作是如何定义的?试说明信号量的 PV 操作的...  操作系统PV操作经典一百... 32页 3下载券 操作系统信号量PV操作题... 7页 ...职场生存攻略 思维导图经典案例 Excel键盘快捷键 Photoshop的抠图技巧分析...  操作系统信号量PV操作题若干_电脑基础知识_IT/计算机_专业资料。(一) 图书馆有 100 个座位,每位进入图书馆的读者要在登记表上登记,退出时要在登记 表上注销。要...  操作系统信号量PV操作题若干_电脑基础知识_IT/计算机_专业资料。操作系统pv操作例子(一) 图书馆有 100 个座位,每位进入图书馆的读者要在登记表上登记,退出时要在...  13页 2下载券 操作系统PV操作经典例题... 4页 1下载券喜欢此文档的还喜欢 ...作业号 1 提交时间 0.0 运行时间 8.0 2 0.4 4.0 3 1.0 1.0 分析 ...  PV操作的例题_其它课程_高中教育_教育专区。PV 操作的例题 一、线程是进程的一...深入地分析和透彻地理解这个例子, 对于全面解决操作系统内的同步、 互斥问题将有...  操作系统pv操作_理学_高等教育_教育专区。很实用的pv操作操作系统P 题解 操作系统 V题解 第一章 The P,V Theorem 在操作系统理论中有一个非常重要的概念叫做P...如果信号量是用于表示一个或多个事件的发生,那么该信号量的初值为什么应设为0_百度知道
如果信号量是用于表示一个或多个事件的发生,那么该信号量的初值为什么应设为0
我有更好的答案
初值为m,表示有m个资源,为0则表示已经没有了资源,如果当前值为-n,那么等待的进程为n。
其他类似问题
为您推荐:
信号量的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 信号量初值设置 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信