【问题标题】: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 秒)。

【问题讨论】:

  • 你的问题听起来更像是一个循环。等待正确的事情并开始另一个请求是一个循环,您不会并行执行任何操作?
  • 我刚刚做了一个编辑,解释了我遇到的问题以及我需要在不同线程上所有这些的原因。

标签: ruby multithreading


【解决方案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 块。
  • 酷,我在找那个,不知道唤醒方法,它会让我睡觉,直到一个线程通知我它准备好了,谢谢。
猜你喜欢
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
相关资源
最近更新 更多