如何等待线程通知而不是加入所有线程? [英] How to wait for Thread notification instead of joining all the Threads?

查看:114
本文介绍了如何等待线程通知而不是加入所有线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简而言之,用户向我的Web服务发出请求,而我必须将请求转发给X个不同的API.我应该并行执行此操作,因此,我为此创建了线程,并且第一个响应有效的答案的线程,我应该杀死其余线程,并立即将答案反馈给我的客户.

In few words, a user makes a request to my web service, and I have to forward the request to X different APIs. I should do it on parallel, so I'm creating threads for this, and the first Thread that answers with a valid response, I should kill the rest of the threads and give back the answer to my customer right away.

Ruby中的一种常见模式是创建多个线程,例如

One common pattern in Ruby, is to create multiple threads like

threads << Thread.new {}
threads.each { |t| t.join }

我已经拥有的逻辑是这样的:

The logic I already have is something like:

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秒内回复一个有效的答案(因此,在这一点上,我应该杀死所有其他线程并退还该答案),但是,我正在加入所有线程并且没有做出反应太有道理了.

But on a code like the previous, I'm blocking the process until all of the threads finish. It could be that one thread will answer back in 1 second with a valid answer (so at this point I should kill all the other threads and give back that answer), but instead, I'm joining all the threads and doesn't make too much sense.

在ruby中有没有办法睡觉或等到一个线程答案,检查该答案是否有效,然后再次阻塞/睡眠,直到所有线程都完成,或者直到其中一个线程给我返回有效响应?

Is there a way in ruby to sleep or wait until one thread answer, check if that answer is valid, and then blocking/sleeping again until all of the threads are done or either until one of them gives me back a valid response?

应该并行进行.当我收到客户的请求时,可以将请求转发给5个不同的公司.

It should be done in parallel. When I get a request from the customer, I can forward the request to 5 different companies.

每家公司最多可以有60秒的超时时间(疯狂但真实的医疗保健业务).

Each company can have a timeout up to 60 seconds (insane but real, healthcare business).

这些公司之一回答后,我必须检查响应(如果是真实响应或错误),如果是真实响应,则应终止所有其他线程并立即答复客户(如果其中一个请求使我超时,则没有理由让他等待60秒).而且,没有理由循环执行它(例如,如果我在循环中执行此操作,则在最坏的情况下大约是5 x 60秒).

As soon as one of these companies answer, I have to check the response (if its a real response or an error), if its a real response, I should kill all of the other threads and answer the customer right away (no reason to make him to wait for 60 seconds if one of the requests gives me back a timeout). Also, no reason to make it on a loop (like if I do this on a loop, it would be like 5 x 60 seconds in the worst scenario).

推荐答案

也许通过使主线程进入睡眠状态?

Perhaps by making the main thread sleep?

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

还有一种更好的唤醒方法:

there is a better approach with wakeup, too:

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

这篇关于如何等待线程通知而不是加入所有线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆