代码之家  ›  专栏  ›  技术社区  ›  Gavin Miller

如果不加入线程,会发生什么?

  •  4
  • Gavin Miller  · 技术社区  · 13 年前

    我正在写一个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 回复  |  直到 13 年前
        1
  •  3
  •   skaz    13 年前

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

        2
  •  2
  •   Gavin Miller    13 年前

    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 same 作为 Thread.new ,所以看起来让线程完成并消亡是可以的。

        3
  •  1
  •   Prine    13 年前

        4
  •  1
  •   Andrew Grimm atk    13 年前

    如果你移除了 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