Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';等待后台线程启动的正确Ruby模式是什么?_Ruby_Multithreading_Condition Variable_Thread Synchronization - Fatal编程技术网

什么';等待后台线程启动的正确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

我需要编写一个Ruby程序来执行后台程序,并在上面执行一些功能

在执行任何操作之前,主线程需要确保后台线程已启动。正确的模式是什么

这并不准确:

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原因是,通常情况下,当通知线程重新获取锁并继续时,等待的条件可能不再保持,例如,在发送通知和通知线程继续之间的时间内,第三个线程突然进入并占用了资源。在问题中的一个相当简单的例子中,这是不会发生的,但也可以看到–不能保证该线程被另一个线程唤醒,因此无论如何,您都应该使用