如何等待线程通知而不是加入所有线程?
Posted
技术标签:
【中文标题】如何等待线程通知而不是加入所有线程?【英文标题】:How to wait for Thread notification instead of joining all the Threads? 【发布时间】:2013-12-19 13:08:58 【问题描述】:简而言之,用户向我的 Web 服务发出请求,我必须将请求转发到 X 个不同的 API。我应该并行执行,所以我为此创建线程,并且第一个回答有效响应的线程,我应该终止其余线程并立即将答案返回给我的客户。
Ruby 中的一个常见模式是创建多个线程,例如
threads << Thread.new
threads.each |t| t.join
我已有的逻辑是这样的:
results = []
threads = []
valid_answer = nil
1.upto(10) do |i|
threads = Thread.new do
sleep(rand(60))
results << i
end
end
threads.each |t| t.join
valid_answer = results.detect |r| r > 7
但是在类似前面的代码中,我会阻塞进程,直到所有线程都完成。可能是一个线程会在 1 秒内回复一个有效的答案(所以此时我应该杀死所有其他线程并返回那个答案),但是相反,我加入了所有线程并且没有太有道理了。
在 ruby 中是否有一种方法可以休眠或等到一个线程回答,检查该回答是否有效,然后再次阻塞/休眠,直到所有线程都完成,或者直到其中一个线程给我一个有效的响应?
编辑:
应该并行进行。当我收到客户的请求时,我可以将请求转发给 5 家不同的公司。
每家公司最多可以有 60 秒的超时时间(疯狂但真实的医疗保健业务)。
一旦其中一家公司回复,我必须检查回复(如果是真实回复或错误),如果是真实回复,我应该杀死所有其他线程并立即回复客户(如果其中一个请求让我返回超时,没有理由让他等待 60 秒)。此外,没有理由在循环中进行(例如,如果我在循环中执行此操作,在最坏的情况下会像 5 x 60 秒)。
【问题讨论】:
你的问题听起来更像是一个循环。等待正确的事情并开始另一个请求是一个循环,您不会并行执行任何操作? 我刚刚做了一个编辑,解释了我遇到的问题以及我需要在不同线程上所有这些的原因。 【参考方案1】:也许通过让主线程休眠?
def do_stuff
threads = []
valid_answer = nil
1.upto(10) do |i|
threads << Thread.new do
sleep(rand(3))
valid_answer ||= i if i > 7
end
end
sleep 0.1 while valid_answer.nil?
threads.each |t| t.kill if t.alive?
valid_answer
end
编辑:唤醒也有更好的方法:
def do_stuff
threads = []
answer = nil
1.upto(10) do |i|
threads << Thread.new do
sleep(rand(3))
answer ||= i and Thread.main.wakeup if i > 7
end
end
sleep
threads.each |t| t.kill if t.alive?
answer
end
【讨论】:
酷,这会起作用,我正在寻找一个系统调用来阻止进程,直到一个线程通知我它准备好或类似的东西,但是你的代码是实用的,它将解决我的问题:)我还应该确保其中一个线程至少正在运行或返回一个错误,但它是一个小更新,再次感谢 :) 我怀疑也有一种方法可以使用 throw/catch 块。 酷,我在找那个,不知道唤醒方法,它会让我睡觉,直到一个线程通知我它准备好了,谢谢。以上是关于如何等待线程通知而不是加入所有线程?的主要内容,如果未能解决你的问题,请参考以下文章