主线程“总是”在像Sinatra这样的ruby Web服务器中运行吗?

时间:2012-05-24 12:13:51

标签: ruby multithreading sinatra

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

Thread.join blocks the main thread类似,但您是否可以在Web请求处理程序向浏览器返回http响应之后调用join并让所有线程按照自己的计划完成?

2 个答案:

答案 0 :(得分:0)

以下代码对我来说很好 - 在OS X本地计算机上测试我能够使用thin和ruby 1.9.2运行1500多个真正的线程。在Heroku雪松堆栈上,我可以在创建线程时遇到错误之前运行大约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" -->

答案 1 :(得分:-1)

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

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

sleep 5

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

另一方面,只要主线程运行,其他线程就可以根据需要运行。请求/响应周期没有任何限制。但请注意,在“原始”Rubies中,线程并不是真正的并发,而是受GIL的约束。如果你想要真正的并发(在你的计算机上使用不同线程的多个核心),你应该看看JRuby或Rubinius(2.0预览版),它们都提供真正的并发线程。

如果你只是想把事情从请求周期中解决以后处理,那么1.8中的绿色线程和1.9中的OS-native-but-GILed线程就可以了。如果您想要更高的可伸缩性,您应该看看delayed_jobResque等技术,这些技术会为后台作业引入持久工作者。