信号量集

来源:百度文库 编辑:神马文学网 时间:2024/04/27 13:32:37
信号量集(主要是AND信号量)
信号量集
当利用信号量机制解决了单个资源的互斥访问后,我们讨论如何控制同时需要多个资源的互斥访问。信号量集是指同时需要多个资源时的信号量操作。
两个进程同时抢点某一类资源时,先给出信号量,用信号时表示这种资源(称之为临界资源)的数量。当资源数量不足时,等待另一个进程释放资源后获得资源。这样完成了互斥进程的调动!
(1)AND型信号量集
AND型信号量集是指同时需要多个资源且每种占用一个资源时的信号量操作。当一段处理代码需要同时获取两个或多个临界资源时,就可能出现由于各进程分别获得部分临界资源并等待其余的临界资源的局面。各进程都会“各不相让”,从而出现死锁。解决这个问题的一个基本思路是:在一个原语中申请整段代码需要的多个临界资源,要么全部分配给它,要么一个都不分配给它。这就是AND型信号量集的基本思想。我们称AND型信号量集P原语为Swait(Simultaneous Wait),V原语为Ssignal(Simultaneous Signal)。在Swait时,各个信号量的次序并不重要,虽然会影响进程归人哪个阻塞队列,但是因为是对资源全部分配或不分配,所以总有进程获得全部资源并在推进之后释放资源,因此不会死锁。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。
下面是Swait和Ssignal的伪代码。
Swait(S1, S2, …, Sn) //P原语; {
while (TRUE)
{
if (S1 >=1 && S2 >= 1 && … && Sn >= 1)
{ //满足资源要求时的处理;
for (i = 1; i <= n; ++i) --Si;
//注:与wait的处理不同,这里是在确信可满足
//资源要求时,才进行减1操作;
break;
}
else
{ //某些资源不够时的处理;
调用进程进入第一个小于1信号量的等待队列Sj.queue;
阻塞调用进程;
}
}
}
(2)一般“信号量集”
一般“信号量集”是指同时需要多种资源、每种占用的数目不同、且可分配的资源还存在一个临界值时的信号量处理。由于—次需要n个某类临界资源,因此如果通过n次wait操作申请这n个临界资源,操作效率很低,并可能出现死锁。—般信号量集的基本思路就是在AND型信号量集的基础上进行扩充,在一次原语操作中完成所有的资源申请。进程对信号量Si的测试值为ti(表示信号量的判断条件,要求Si>ti即当资源数量低于ti时,便不予分配),占用值为di(表示资源的申请量,即Si=Si—di)。对应的P、V原语格式为:
Swait(S1, t1, d1; ...; Sn, tn, dn);
Ssignal(S1, d1; ...; Sn, dn);
一般“信号量集”可以用于各种情况的资源分配和释放。下面是几种特殊的情况:
1)Swait(S,d,d)表示每次申请d个资源,当资源数量少于d个时,便不予分配。
2)Swait(S,1,1)表示互斥信号量。
3)Swait(S,1,0)可作为一个可控开关(当S≥1时,允许多个进程进入临界区;当S=0时禁止任何进程进入临界区)。
由于一般信号量在使用时的灵活性,因此通常并不成对使用Swait和Ssignal。为了避免死锁可一起申请所有需要的资源,但不一起释放。