信号量操作

时间:2012-12-22 18:08:58

标签: c semaphore

我正在阅读有关信号量及其操作的文本。作者强调,信号量的wait()post()操作应该以原子方式执行,否则可能会违反线程的互斥。请问任何人,请向我解释他的意思?

,我是多线程的新手

2 个答案:

答案 0 :(得分:2)

上下文切换的操作,其中任务/进程被内核替换为另一个任务/进程是异步和不确定的。

让我们检查以下代码:

x++;
看起来很简单,哈? 但是,如果x在不同的任务/进程之间共享,则此代码容易出现同步错误。

要理解这一点,你必须理解原子操作的概念。

原子操作是处理器可以在单个时钟上执行的指令。 它通常涉及读取寄存器,写入寄存器等等。

回到代码示例: 在递增变量时,幕后(汇编)实际发生的是 cpu将变量的值读入寄存器。 然后,它增加它。 然后它将它保存回原始位置(内存)。

正如您所看到的,这样的简单操作涉及3个cpu步骤。 上下文切换可以在这3个步骤之间进行。

让我们举两个需要增加相同变量x的线程的例子。

让我们检查虚构(但可能)场景的伪汇编代码

  1. 读取要注册的值(线程1)
  2. 增加值(线程1) 上下文开关
  3. 读取要注册的值(线程2)
  4. 增加值(线程2)
  5. 保存值(线程2) 上下文开关
  6. 保存值(主题1)
  7. 如果x为3,则现在看起来需要为5,但它将为4。

    现在,让我们来看你原来的问题。 信号量/互斥量实际上是一个变量。 当一个过程想要接受它时,它会增加它。

答案 1 :(得分:0)

是的,如果信号量上的wait()post()操作没有原子地执行,则可以违反线程的相互执行。

例如,考虑一个值为S = 1且流程P1P2的信号量尝试同时执行wait()的信号量,

在时间T0T1进程P1P2分别找到信号量的值为S = 1,然后递减信号量以获取锁定和同时进入临界区,违反了线程的相互执行。

wait()post() spin-locking之间使用原子性,直到获得锁定为止。