1

当您从 Web 请求处理程序中启动线程时 - 只要服务器正在运行,该线程是否会继续运行?

类似于Thread.join 会阻塞主线程,但您能否不调用 join 并让所有线程按自己的计划完成,很可能是在 Web 请求处理程序向浏览器返回 http 响应之后?

4

2 回答 2

0

下面的代码对我来说很好——在 OS X 本地机器上测试我能够得到 1500+ 个真正的线程,运行 Thin 和 ruby​​ 1.9.2。在 Heroku cedar 堆栈上,在创建线程时出现错误之前,我可以运行大约 230 个线程。

在这两种情况下,所有线程似乎都在它们应该完成的时候完成 - 启动它们后 2 分钟。'/' 在 Heroku 上渲染大约 60 毫秒,然后 20 个线程每个运行 2 分钟。

如果你刷新/几次,然后等待几分钟,你可以看到线程正在整理。我测试 2 分钟的原因是 heroku 对响应有 30 秒的限制,如果你花的时间超过这个时间,就会把你打断。但这似乎不会影响后台线程。

$threadsLaunched = 0
$$threadsDone = 0

get '/' do
  puts "#{Thread.list.size} threads"
  for i in 1..20 do
      $threadsLaunched = $threadsLaunched + 1
      puts "Creating thread #{i}"
      Thread.new(i) do |j|
          sleep 120
          puts "Thread #{j} done"
          $threadsDone = $threadsDone + 1
      end
   end
  puts "#{Thread.list.size} threads"
  erb :home
 end

(home.erb)

   <div id="content">

<h1> Threads launched <%= $threadsLaunched.to_s %> </h1>
<h1> Threads running <%= Thread.list.count.to_s %> </h1>
<h1> Threads done <%= $threadsDone.to_s %> </h1>

 </div> <!--  id="content" -->
于 2012-05-24T14:05:06.553 回答
-1

一旦你的主线程退出,所有其他的也被强制销毁并且进程退出。

Thread.new do
  # this thread never exists on its own
  while true do
    puts "."
    sleep 1
  end
end

sleep 5

按照这个例子,一旦主线程结束,打印线程也将结束而没有“完成”它的工作。在退出主线程之前,您必须明确join所有后台线程等待它们完成。

另一方面,只要主线程运行,其他线程就可以随心所欲地运行。请求/响应周期没有任意限制。但是请注意,在“原始”红宝石中,线程并不是真正并发的,而是受制于 GIL。如果您想要真正的并发(例如在您的计算机上使用具有不同线程的多核),您应该看看 JRuby 或 Rubinius(2.0 预览版),它们都提供真正的并发线程。

如果您只是想将事情从请求周期中取出以便稍后处理,那么 1.8 中的绿色线程和 1.9 中的 OS-native-but-GILed 线程就可以了。如果你想要更多的可扩展性,你应该看看像delayed_jobResque这样的技术,它们为后台作业引入了持久化的worker。

于 2012-05-24T12:41:21.270 回答