信号量中的原子指令

Posted

技术标签:

【中文标题】信号量中的原子指令【英文标题】:Atomic instructions in semaphores 【发布时间】:2021-12-16 09:39:55 【问题描述】:

我很困惑信号量是原子的意味着什么。等待和信号的定义如下。

wait(S)
    while ( S<= 0)
        ; // Busy wait
        S--;



signal(S) 
    S++;

书上说

wait()中对大二整数值的所有修改 和 signal() 操作必须以原子方式执行。也就是说,当一个 进程修改信号量值,其他进程不能 同时修改相同的信号量值

这是否意味着在while(S&lt;=0)S-- 之间不能执行其他指令?以及在什么时候完成修改信号量值的过程?这是它最终递减S--的时候吗?

【问题讨论】:

'等待和信号的定义如下' - 请注意,虽然它可能是某些网站上的一些定义,但它并不通用。内核同步对象,如信号量,并不总是忙等待。 【参考方案1】:

这是否意味着在 while(S

没有。这意味着所有修改(例如S--)必须以原子方式完成,即没有其他进程可以同时尝试修改S,例如通过执行signal中的S++

修改信号量值的过程在什么时候完成?这是它最终递减S--的时候吗?

正如解释所说,每个修改都必须是原子的。所以它在每次修改结束时修改了值。它可能会再次修改它,但这将是一个独特的修改,也必须是原子的。

您可以将“原子修改”视为不与任何其他原子访问或修改重叠的修改。如果S++S-- 不是原子的,则操作可能会丢失,例如,如果两个进程执行S++ 并且它们的操作重叠。它们都可以读取S,都增加S,然后都写入S,导致S 只增加一次。

【讨论】:

【参考方案2】:

任何操作 是原子的意味着:要么发生,要么不发生。如果某个线程 A 对某个数据集合或某个对象执行原子操作,并且线程 B 检查对象/数据,那么线程 B 必须看到对象/数据在操作开始之前或之后手术结束。 “原子”意味着线程 B 不可能看到处于中途完成状态的对象/数据。

我们可以通过在访问数据时使用synchronized 块或ReentrantLock 对象来提供原子性,但是如果有人告诉您某些对象 是原子的,那么他们所说的是,所有的您可以对其执行的操作*自动保证是原子的,无需您显式锁定任何内容。


* 特殊情况除外,在对象的文档中注明。

【讨论】:

以上是关于信号量中的原子指令的主要内容,如果未能解决你的问题,请参考以下文章

Linux驱动开发原子操作自旋锁信号量互斥体

ARM指令集—SWP指令

Linux 并发与竞争(原子操作自旋锁信号量互斥体)

ARM指令集—SWP指令

获取信号量必须是原子的。 Pintos 的 sema_down 安全吗?

自旋锁互斥锁信号量原子操作条件变量在不同开源框架的应用