通过线程无法正常工作来提高ruby代码的性能

时间:2011-08-22 00:44:57

标签: ruby multithreading

我正在尝试使用Thread优化这段ruby代码,这涉及到相当多的IO和网络活动。不幸的是,这并没有太好。

# each host is somewhere in the local network
hosts.each { |host|
  # reach out to every host with something for it to do
  # wait for host to complete the work and get back
}

我最初的计划是将循环内部包装到每次迭代的新线程中。类似的东西:

# each host is somewhere in the local network
hosts.each { |host|
  Thread.new { 
  # reach out to every host with something for it to do
  # wait for host to complete the work and get back
  }
}

# join all threads here before main ends

我希望自从这个I / O绑定甚至没有ruby 1.9我应该能够获得一些东西,但没有,没有。有什么想法可以改进吗?

3 个答案:

答案 0 :(得分:1)

我不确定你有多少台主机,但如果它很多,你可能想尝试一个具有固定线程数的生产者/消费者模型:

require 'thread'

THREADS_COUNT = (ARGV[0] || 4).to_i

$q = Queue.new
hosts.each { |h| $q << h }

threads = (1..THREADS_COUNT).map {
  Thread.new {
    begin
      loop {
        host = $q.shift(true)

       # do something with host
      }
    rescue ThreadError
      # queue is empty, pass
    end
  }
}

threads.each(&:join)

如果这太复杂了,您可以尝试使用xargs -P。 ;)

答案 1 :(得分:1)

@ Fanatic23,在得出任何结论之前,使用puts检测代码并查看网络请求是否实际重叠。在每次调用puts时,打印一个状态字符串,指示正在执行的行,以及Time.nowTime.now.nsec

答案 2 :(得分:-1)

你说“因为即使没有红宝石1.9这也是I / O绑定我应该能够获得一些东西”。

虚荣的希望。 : - )

当Ruby 1.8中的某个线程阻塞IO时,整个进程已阻止IO。这是因为它使用了绿色的theads。

升级到Ruby 1.9,您将可以访问平台的本机线程实现。有关更多信息,请参阅:

http://en.wikipedia.org/wiki/Green_threads

享受!