我正在进行流程同步,并且难以理解信号量。所以这是我的疑问:
消息来源说
“信号量S是一个整数变量,可通过标准原子操作访问,即wait()和signal()。
它还提供了wait()
的基本定义wait(Semaphore S)
{
while S<=0
; //no operation
S--;
}
signal()的定义
signal(S)
{
S++;
}
让信号量的初始值为1,并说有两个并发进程P0和P1不应同时执行其临界区的操作。
现在说P0处于其关键部分,因此信号量S必须具有值0,现在说P1想要进入其临界区,因此它执行wait(),并且在wait()中它连续循环,现在退出信号量值必须递增的循环,但它可能是不可能的,因为根据源,wait()是原子操作并且不能被中断,因此进程P0不能在单个处理器系统中调用signal()
我想知道,到目前为止我的理解是否正确。如果正确那么当进程P1在循环中被触发时,进程P0如何调用signal()?
答案 0 :(得分:5)
我认为这是您的来源不准确。 Atomic
操作的wait()
表示它的每次迭代都是atomic
,意味着S--
不会中断,但每次完成{{1}后整个操作都是可中断的} S--
循环内部。
答案 1 :(得分:3)
我认为最高投票的答案是不准确的!
操作wait()和signal()必须是完全原子的;没有两个进程可以同时执行wait()或signal()操作,因为它们是在内核中实现的,内核态的进程不能被抢占。
如果多个进程同时尝试 P(S),则只允许一个进程继续进行(没有竞争条件的非抢占内核)。
要使上述实现工作抢占是必要的(抢占内核)
了解信号量操作的原子性 http://personal.kent.edu/~rmuhamma/OpSystems/Myos/semaphore.htm https://en.wikibooks.org/wiki/Operating_System_Design/Processes/Semaphores
答案 2 :(得分:1)
我不认为,在wait()操作中保持无限的while循环是明智的。我会选择Stallings的例子;
void semWait(semaphore s){
s.count--;
if(s.count<0)
*place this process in s.queue and block this process
}
答案 3 :(得分:0)
当任务尝试获取不可用的信号量时,信号量将任务置于等待队列并将任务置于休眠状态。然后处理器可以自由执行其他代码。信号量变得可用,等待队列上的任务之一被唤醒,以便它可以获取信号量。
而S <= 0 ; //无操作这并不意味着处理器运行此代码。进程/任务被阻塞,直到获得信号量。
答案 4 :(得分:0)
我认为本书对原子操作的意义在于测试S<=0
为真,以及S--
。就像之前提到的testAndset()
一样。
如果单独的操作S<=0
和S--
都是原子操作但可以被其他进程中断,则此方法无法正常工作。
想象两个进程p0和p1,如果p0想要进入临界区并且测试S<=0
为真。它被p1打断,测试S<=0
也是如此。然后这两个过程都将进入临界区。那是错的。
实际非原子操作在while循环内部,即使while循环为空,当S<=0
测试为false时,其他进程仍然可以中断当前进程,这使得其他进程可以继续其关键工作部分并释放锁。
然而,我认为本书中的代码实际上并不能在操作系统中使用,因为我不知道如何使操作S<=0
成为真,而S--
一起使用原子。更可行的方法是将S--
置于while循环中,如SomeWittyUsername所述。
答案 5 :(得分:0)