我正在学习期中考试,这是一个练习题:展示如何使用二进制信号量和普通机器指令来实现计数信号量(即可以保持任意值的信号量)?
我甚至不确定从哪里开始。我在网上找到了这个;
P(s) { Pb(mutex_s); s = s-1; if(s < 0) {Vb(mutex_s); Pb(delay_s);} Vb(mutex_s); }
V(s) { Pb(mutex_s); s = s+1; if(s <= 0) Vb(delay_s); else Vb(mutex_s); }
不幸的是,我真的不明白答案告诉我的是什么。任何人都可以向我解释这个答案,或者用伪代码告诉我如何回答?
答案 0 :(得分:5)
我在Prahbat's回答中建立了以下直觉:
我们想要复制的内容:
我们可以使用二进制信号量来做到这一点:
因此,以下伪代码表明了自己
P_counting( int count )
P( countLock ) // Acquire lock to count: countLock <- 0
count--
if( count <= 0 ) // If no more threads allowed into critical section
P( sectionLock ) // Resource full => Acquire section lock: sectionLock <- 0
V( countLock ) // Release lock to count: countLock <- 1
else
V( countLock)
V_counting( int count )
P( countLock )
count++
if( count > 0) // Release sectionLock if resource is freed up
V(sectionLock) // countLock released after sectionLock so that waiting
V(countLock) // threads do not jump in when before resource is available
else
V(countLock)
如果我出错了,请告诉我。
答案 1 :(得分:2)
设x,y为二进制信号量。我们将通过它实现计数信号量S.P代表等待操作,V代表信号。 由于我们采用S = 4,因此只有4个过程可以进入关键部分。
S = 4, x = 1, y = 0;
/*---P(S)---*/
{P(x);S--;if(s<=0){V(x);P(y);}else V(x); }
/*--CRITICAL SECTION--*/
/*--V(S) ---*/
{ P(x); S++;IF(S>0){ V(y);V(x); }else V(x);}
注意:P(x)将x的值减小1,而V(x)增加1,y的值相同。 y被称为悬挂信号量,因为P(y)表示所有这些 如果S&lt;队列中的进程0.
答案 2 :(得分:2)
CSem(K) cs { // counting semaphore initialized to K
int val ← K; // the value of csem
BSem gate(min(1,val)); // 1 if val > 0; 0 if val = 0
BSem mutex(1); // protects val
Pc(cs) {
P(gate)
a1: P(mutex);
val ← val − 1;
if val > 0
V(gate);
V(mutex);
}
Vc(cs) {
P(mutex);
val ← val + 1;
if val = 1
V(gate);
V(mutex);
}
}
来源:http://www.cs.umd.edu/~shankar/412-Notes/10x-countingSemUsingBinarySem.pdf
答案 3 :(得分:0)
想出来:
int s = N;
semaphore mutex_s = 1;
semaphore delay_s = 0;
p(s) = down
down(mutex_x);
s--;
if (s< n)
up(mutex_s)
down(delay_s)
up(mutex_s)
V(s) = up
down(mutex_s)
s++
if (s<=0)
up(delay_s)
up(mutex_s)
答案 4 :(得分:0)
我有一个类似的问题,我认为会有相同的答案,即“如何使用互斥锁实现计数信号量”。
请注意,二进制信号量可以被认为是互斥量。实际上,在不提供互斥锁的系统上,可以使用二进制信号量来提供互斥。
Mutex counting_mutex; // used for accessing the shared variable count
Integer count = n; // number of resource instances
Mutex mutex; // the counting semaphore as mutex/binary semaphore
List waiting_list = []; // list of waiting processes
/* ... */
// Entry Section
acquire(counting_mutex);
count--;
release(counting_mutex);
if (count < 0)
add this process to waiting_list and have it sleep()
acquire(mutex);
/* ... Critical Section ... */
release(mutex);
// Exit Section
acquire(counting_mutex);
count++;
release(counting_mutex);
if (count <= 0)
pull a process from waiting_list and call wakeup()