什么';等待后台线程启动的正确Ruby模式是什么?
我需要编写一个Ruby程序来执行后台程序,并在上面执行一些功能 在执行任何操作之前,主线程需要确保后台线程已启动。正确的模式是什么 这并不准确:什么';等待后台线程启动的正确Ruby模式是什么?,ruby,multithreading,condition-variable,thread-synchronization,Ruby,Multithreading,Condition Variable,Thread Synchronization,我需要编写一个Ruby程序来执行后台程序,并在上面执行一些功能 在执行任何操作之前,主线程需要确保后台线程已启动。正确的模式是什么 这并不准确: condition = ConditionVariable.new mutex = Mutex.new thread = Thread.new do mutex.synchronize { condition.signal } # background work end mutex.synchronize { condition.wait
condition = ConditionVariable.new
mutex = Mutex.new
thread = Thread.new do
mutex.synchronize { condition.signal }
# background work
end
mutex.synchronize { condition.wait(mutex) }
# other work
因为:signal
可以在:wait
之前执行,从而阻塞了主线程
精确的解决方案是:
thread = Thread.new do
Thread.current[:started] = true
# background work
end
sleep 0.01 while thread[:started].nil?
# other work
mutex = Mutex.new
condition = ConditionVariable.new
thread = Thread.new do
mutex.synchronize do
Thread.current[:started] = true
condition.signal
end
# background work
end
mutex.synchronize do
condition.wait(mutex) if !thread[:started]
end
# other work
但是,它使用了睡眠
,这是我想要避免的
另一个精确但更复杂的解决方案是:
thread = Thread.new do
Thread.current[:started] = true
# background work
end
sleep 0.01 while thread[:started].nil?
# other work
mutex = Mutex.new
condition = ConditionVariable.new
thread = Thread.new do
mutex.synchronize do
Thread.current[:started] = true
condition.signal
end
# background work
end
mutex.synchronize do
condition.wait(mutex) if !thread[:started]
end
# other work
是否有任何精确、简单且惯用的方法来构造此功能?您可以使用:
将等待项目可用并返回。您不能使用
睡眠
,也只能在循环中等待。我不认为在循环中等待有什么错。@JoshVoigts如果我理解得很好,我也想到了同样的称呼,但是更复杂,因为它需要一个互斥体和一个条件变量来获得等待()
机制。我将在问题中添加代码。谢谢您的最后一个示例几乎就是这样做的,尽管我会使用显式变量而不是线程本地变量,并将wait
包装在while
中,而不仅仅是if
@JoshVoigts,我对此不太确定。自己试试,打开一个irb并运行,直到false;结束
-找到PID,并在过程监视器中查找它。。。对我来说,这花费了将近100%的cpu。@Marcus原因是,通常情况下,当通知线程重新获取锁并继续时,等待的条件可能不再保持,例如,在发送通知和通知线程继续之间的时间内,第三个线程突然进入并占用了资源。在问题中的一个相当简单的例子中,这是不会发生的,但也可以看到–不能保证该线程被另一个线程唤醒,因此无论如何,您都应该使用而。