2010-11-04 112 views
4

我正在寫一個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 

我更傾向於將跳過加入線程,而不是阻止整個應用程序。然而,我不知道這會帶來什麼長期影響,特別是因爲代碼幾乎立即運行。這是安全的嗎?還是有更好的方法來產生一個線程,讓它工作,並完成時清理,都在一個無限循環內?

回答

2

寫後問題出來了,我意識到這是Web服務器在提供頁面時確實需要做的事情。我搜索了一下,發現了以下文章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.startis effectively the sameThread.new,所以看來讓線程完成並死光是確定的事情。

3

我認爲這取決於你的線程工作的內容。例如,如果您的主線程需要打印「X已完成」,則需要加入以確保您顯示正確的答案。如果你沒有這樣的要求,那麼你不一定需要加入。

+1

的線程不需要報到主程序。 – 2010-11-04 18:29:09

1

如果拆分工作負載到幾個不同的線程,你需要在最後的解決方案,從你肯定需要否則加入不同的線程相結合,你可以做到這一點沒有加入..

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 
+0

紅寶石隊列線程安全嗎? – 2010-11-06 14:19:31

+0

@Gavin:文檔提到了線程,而類來自'thread.rb'。但是,它不使用「線程安全」這些字樣。如果你想讓他們明確地說它是線程安全的,我可以提交一個文檔錯誤。 – 2010-11-07 00:27:43

+0

我沒有發現它來自'thread.rb',這對我來說足夠了!我通常在.NET中編程,所以我習慣於明確的「這是線程安全的」vs「這不是線程安全的」 – 2010-11-07 03:03:13

相關問題