【问题标题】:How to asynchronously collect results from new threads created in real time in ruby如何从 ruby​​ 中实时创建的新线程中异步收集结果
【发布时间】:2014-07-12 01:31:27
【问题描述】:

我想不断检查数据库中的表以运行命令。 有些命令可能需要 4 分钟才能完成,大约 10 秒。

因此我想在线程中运行它们。所以每条记录都会创建新的线程,线程创建后,记录会被删除。

由于数据库查找+线程创建将在无限循环中运行,我如何从线程中获取“响应”(线程将发出 shell 命令并获取我想阅读的响应代码)?

我考虑过创建两个线程,每个线程都有无限循环: - 首先用于数据库查找 + 创建新线程 - 第二个......以某种方式读取线程结果并根据每个响应采取行动

或者我应该使用 fork,或者 os 生成一个新进程?

【问题讨论】:

  • 您能否让每个命令线程获取响应代码并将其存储回数据库,作为同一记录的一部分?

标签: ruby multithreading process thread-safety spawn


【解决方案1】:

您可以让每个线程将其结果推送到队列中,然后您的主线程可以从队列中读取。默认情况下,从队列中读取是阻塞操作,因此如果没有结果,您的代码将阻塞并等待读取。

http://ruby-doc.org/stdlib-2.0.0/libdoc/thread/rdoc/Queue.html

这是一个例子:

require 'thread'

jobs = Queue.new
results = Queue.new

thread_pool = []
pool_size = 5

(1..pool_size).each do |i|
  thread_pool << Thread.new do 
    loop do 
      job = jobs.shift #blocks waiting for a task
      break if job == "!NO-MORE-JOBS!"

      #Otherwise, do job...
      puts "#{i}...."
      sleep rand(1..5) #Simulate the time it takes to do a job
      results << "thread#{i} finished #{job}"  #Push some result from the job onto the Queue
      #Go back and get another task from the Queue
    end
  end
end


#All threads are now blocking waiting for a job...
puts 'db_stuff'
db_stuff = [
  'job1', 
  'job2', 
  'job3', 
  'job4', 
  'job5',
  'job6',
  'job7',
]

db_stuff.each do |job|
  jobs << job
end

#Threads are now attacking the Queue like hungry dogs.

pool_size.times do
  jobs << "!NO-MORE-JOBS!"
end

result_count = 0

loop do
  result = results.shift
  puts "result: #{result}"
  result_count +=1
  break if result_count == 7
end

【讨论】:

  • 当谈到队列时 - push 和 pop 是常规使用,而不是 &lt;&lt; 和 shift
  • 太棒了。这完美地工作。还有一个问题。有时线程被杀死如何重新创建一个新线程来填满池?
猜你喜欢
  • 1970-01-01
  • 2017-07-18
  • 1970-01-01
  • 2020-01-28
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
相关资源
最近更新 更多