8

我正在经历进程同步,并且在理解信号量方面遇到困难。所以这是我的疑问:

消息来源说

" Semaphore S 是一个整数变量,可以通过标准原子操作访问,即 wait() 和 signal()。

它还提供了 wait() 的基本定义

wait(Semaphore S)
{
   while S<=0
     ; //no operation
   S--;
}

信号()的定义

signal(S)
{
   S++;
}

假设信号量的初始值为 1,假设有两个并发进程 P0 和 P1,它们不应该同时执行其临界区的操作。

现在说 P0 在它的临界区,所以信号量 S 必须有值 0,现在说 P1 想进入它的临界区,所以它执行 wait(),在 wait() 中它不断循环,现在退出循环信号量值必须递增,但这可能是不可能的,因为根据来源,wait() 是原子操作,不能被中断,因此进程 P0 不能在单处理器系统中调用 signal()。

我想知道,到目前为止我的理解是否正确。如果正确,那么当进程 P1 在 while 循环中被触发时,进程 P0 如何调用信号()?

4

6 回答 6

5

我认为这是您的来源不准确。Atomic对于wait()操作意味着它的每次迭代atomic,意思S--是不间断地执行,但整个操作在循环S--内每次完成后都是可中断的。while

于 2012-11-23T13:17:34.270 回答
4

我认为投票最多的答案是不准确的!

操作 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

于 2021-01-13T03:03:58.210 回答
2

我不认为,在 wait() 操作中保持无限循环是明智的。我会选择 Stallings 的例子;

void semWait(semaphore s){
    s.count--;
    if(s.count<0)
        *place this process in s.queue and block this process
}
于 2014-01-03T03:54:35.447 回答
1

我认为这本书对原子操作的意义在于测试S<=0是否为真S--。就像testAndset()之前提到的一样。

如果两个单独的操作S<=0都是S--原子的但可以被其他进程中断,则此方法将不起作用。

想象两个进程 p0 和 p1,如果 p0 想进入临界区并测试S<=0为真。它被 p1 打断并且测试S<=0也是正确的。那么这两个过程都会进入临界区。这是错误的。

实际的非原子操作在while循环内部,即使while循环为空,其他进程在S<=0测试为假时仍然可以中断当前的一个,这使得其他进程可以在临界区继续工作并释放锁。

但是,我认为这本书中的代码实际上不能在操作系统中使用,因为我不知道如何使操作S<=0成为真实的并且是S--原子的。更多可能的方法是S--像 SomeWittyUsername 所说的那样把 while 循环放在里面。

于 2017-09-20T12:02:44.173 回答
0

当一个任务试图获取一个不可用的信号量时,信号量将任务放入等待队列并使任务进入睡眠状态。然后处理器可以自由地执行其他代码。当信号量变得可用时,任务中的一个等待队列被唤醒,以便它可以获取信号量。

而 S<=0 ; //无操作 这并不意味着处理器运行这段代码。进程/任务被阻塞,直到它获得信号量。

于 2013-02-27T08:43:03.850 回答
0

我认为,当进程 P1 在 while 循环中被击中时,它将处于等待状态。处理器将在进程 p0 和 p1 之间切换(上下文切换),因此优先级转到 p0 并调用 signal() 然后 s 将是加 1,p0 退出该部分,因此进程 P1 可以进入临界区,可以避免互斥

于 2017-10-08T12:18:52.433 回答