当你不加入你的主题时会发生什么?

时间:2010-11-04 18:20:33

标签: ruby multithreading

我正在编写一个ruby程序,它将使用线程来完成一些工作。正在完成的工作需要非确定的时间来完成,范围可以是5到45秒。下面是线程代码的粗略示例:

loop do                         # Program loop
  items = get_items
  threads = []

  for item in items
    threads << Thread.new(item) do |i|
      # do work on i
    end

    threads.each { |t| t.join } # What happens if this isn't there?
  end
end

我的偏好是跳过加入线程而不是阻止整个应用程序。但是我不知道这是什么长期影响,特别是因为代码几乎立即再次运行。这是安全的吗?或者是否有更好的方法来生成一个线程,让它工作,并在它完成后清理,所有这些都在一个无限循环中?

4 个答案:

答案 0 :(得分:3)

我认为这实际上取决于你的线程工作的内容。例如,如果您的主线程需要打印“X work done”,您需要加入以确保您显示正确的答案。如果您没有这样的要求,那么您不一定需要加入。

答案 1 :(得分:2)

在写完问题之后,我意识到这是Web服务器在提供页面时所做的事情。我用Google搜索并找到了Ruby web server的以下文章。循环代码看起来非常像我的:

loop do
  session = server.accept
  request = session.gets
  # log stuff

  Thread.start(session, request) do |session, request|
    HttpServer.new(session, request, basePath).serve()
  end
end

Thread.start is effectively the sameThread.new,因此看起来让线程完成并死掉是可以的。

答案 2 :(得分:1)

如果您将工作负载拆分为多个不同的线程,并且您需要在最后组合来自不同线程的解决方案,您肯定需要加入,否则您可以在没有连接的情况下进行此操作。

答案 3 :(得分:1)

如果您删除了join,那么最终新项目的启动速度可能会比旧版本更快完成。如果您同时处理太多项目,可能会导致性能问题。

您应该使用队列(来自http://ruby-doc.org/stdlib/libdoc/thread/rdoc/classes/Queue.html的代码段):

  require 'thread'

  queue = Queue.new

  producer = Thread.new do
    5.times do |i|
      sleep rand(i) # simulate expense
      queue << i
      puts "#{i} produced"
    end
  end

  consumer = Thread.new do
    5.times do |i|
      value = queue.pop
      sleep rand(i/2) # simulate expense
      puts "consumed #{value}"
    end
  end

  consumer.join