信号量中的原子指令
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<=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
对象来提供原子性,但是如果有人告诉您某些对象 是原子的,那么他们所说的是,所有的您可以对其执行的操作*自动保证是原子的,无需您显式锁定任何内容。
* 特殊情况除外,在对象的文档中注明。
【讨论】:
以上是关于信号量中的原子指令的主要内容,如果未能解决你的问题,请参考以下文章