class Thread::ConditionVariable
ConditionVariable 对象是对类 Mutex 的一个补充。使用条件变量,可以在临界区内暂停,直到满足某个条件,例如资源可用。
由于非确定性调度和虚假唤醒,条件变量的用户在使用前,应始终使用一个单独的布尔谓词(例如读取布尔变量)来检查条件是否实际满足,并且应该在一个循环中等待,每次 ConditionVariable 被唤醒时重新检查条件。使用条件变量的惯用方法是在一个 until 循环中调用 wait 方法,并将谓词作为循环条件。
condvar.wait(mutex) until condition_is_met
在下面的示例中,我们使用布尔变量 resource_available(受 mutex 保护)来指示资源的可用性,并使用 condvar 来等待该变量变为 true。请注意,
-
Threadb可能在线程a1和a2之前被调度,并且可能运行得非常快,以至于在a1或a2开始之前就已经使资源可用。因此,a1和a2在开始等待之前,应该检查resource_available是否已经为 true。 -
wait方法可能会在没有收到信号的情况下发生虚假唤醒。因此,线程a1和a2在wait方法返回后,应该重新检查resource_available,如果条件未实际满足,则返回等待。 -
线程
a2可能在线程a1被b唤醒后立即开始。线程a2可能在线程a1获得mutex之前就获得了mutex并消耗了资源。这使得在wait之后也需要重新检查。
示例
mutex = Thread::Mutex.new resource_available = false condvar = Thread::ConditionVariable.new a1 = Thread.new { # Thread 'a1' waits for the resource to become available and consumes # the resource. mutex.synchronize { condvar.wait(mutex) until resource_available # After the loop, 'resource_available' is guaranteed to be true. resource_available = false puts "a1 consumed the resource" } } a2 = Thread.new { # Thread 'a2' behaves like 'a1'. mutex.synchronize { condvar.wait(mutex) until resource_available resource_available = false puts "a2 consumed the resource" } } b = Thread.new { # Thread 'b' periodically makes the resource available. loop { mutex.synchronize { resource_available = true # Notify one waiting thread if any. It is possible that neither # 'a1' nor 'a2 is waiting on 'condvar' at this moment. That's OK. condvar.signal } sleep 1 } } # Eventually both 'a1' and 'a2' will have their resources, albeit in an # unspecified order. [a1, a2].each {|th| th.join}
Public Class Methods
Source
# File thread_sync.rb, line 156 def initialize end
Document-method: ConditionVariable::new
创建一个新的条件变量实例。