开发者

What happens when you don't join your Threads?

I'm writing a ruby program that will be using threads to do some work. The work that is being done takes a non-deterministic amount of time to complete and can range anywhere from 5 to 45+ seconds. Below is a rough example of what the threading code looks like:

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

My preference would be to skip joining the threads and not block the entire application. However I don't know what the long term implications of this are, especially because the code is run again almost immediately. Is this开发者_如何学运维 something that is safe to do? Or is there a better way to spawn a thread, have it do work, and clean up when it's finished, all within an infinite loop?


I think it really depends on the content of your thread work. If, for example, your main thread needed to print "X work done", you would need to join to guarantee that you were showing the correct answer. If you have no such requirement, then you wouldn't necessarily need to join up.


After writing the question out, I realized that this is the exact thing that a web server does when serving pages. I googled and found the following article of a Ruby web server. The loop code looks pretty much like mine:

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 same as Thread.new, so it appears that letting the threads finish and die off is OK to do.


If you split up a workload to several different threads and you need to combine at the end the solutions from the different threads you definately need a join otherwise you could do it without a join..


If you removed the join, you could end up with new items getting started faster than the older ones get finished. If you're working on too many items at once, it may cause performance issues.

You should use a Queue instead (snippet from 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜