2010-11-04 1 views
4

Я пишу рубиновую программу, которая будет использовать потоки для выполнения некоторой работы. Выполняемая работа требует не детерминированного количества времени для завершения и может варьироваться от 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

После написания вопрос, я понял, что это то, что делает веб-сервер при обслуживании страниц. Я googled и нашел следующую статью 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 same, как Thread.new, так что кажется, что позволяя нити закончить и отмирают в порядке, чтобы сделать.

3

Я думаю, что это действительно зависит от содержания вашей работы с нитками. Если, например, ваш основной поток должен был распечатать «X done done», вам нужно будет присоединиться, чтобы гарантировать правильный ответ. Если у вас нет такого требования, вам необязательно будет объединяться.

+1

Нити не нужно сообщать обратно в основной программе. –

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

Действительно ли очереди рубинов в очереди? –

+0

@Gavin: в документации упоминаются потоки, а класс - из 'thread.rb'. Однако в нем не используются слова «thread safe». Если вы предпочтете, чтобы они прямо сказали, что это потокобезопасный, я могу подать ошибку в документации. –

+0

Я не понял, что это из 'thread.rb', это достаточно для меня достаточно! Я обычно программирую в .NET, поэтому я привык к явному «это потокобезопасный» vs «это не потокобезопасно», –

Смежные вопросы