jRuby线程 - 我做得对吗?

时间:2017-06-22 11:25:39

标签: ruby multithreading jruby

你介意我告诉我是否在Ruby中正确地进行了线程化吗?

我有一个数组items,我希望在16个线程中处理,等待所有线程完成,然后再做更多工作。

这是我的代码;

    chunks = items.each_slice(items.count / 16).to_a
puts chunks.length

queue = Queue.new
semaphore = Mutex.new
threads = []

puts '[+] Building Queue'
chunks.each do |chunk|
    threads << Thread.new {
        chunk.each do |item|
            array = []
            metadata.each do |m|
                array << m.evaluate(item) rescue ''
            end
semaphore.synchronize {
    queue << array.join(20.chr)
}
        end
    }
end
puts '[+] Running threads'
threads.each{|t|t.join; puts 'Threads done'}

#Do more work here, queue should be fully populated
puts '[+] Writing to file'
File.open('E:/Export.dat', 'wt', encoding: 'UTF-16LE') do |f|
    until queue.empty?
        unit = queue.pop(true) rescue nil
        if unit
            f.puts unit
        end
    end
end

代码运行,但是没有给出我期望的线程性能,这是正确的吗?

由于

1 个答案:

答案 0 :(得分:0)

您不太可能看到性能提升,因为每个线程都阻止将结果添加到队列中。 Queue类是线程安全的,因此您不需要Mutex来保护它。

为了使多线程代码更好地工作,您希望每个线程尽可能独立地运行。以下实施应改善性能。

chunks = items.each_slice(items.count / 16).to_a
puts chunks.length

queue = Queue.new
threads = []

puts '[+] Building Queue'
chunks.each do |chunk|
    threads << Thread.new do
        chunk.each do |item|
            array = []
            metadata.each do |m|
                array << m.evaluate(item) rescue ''
            end
            queue << array.join(20.chr)
        end
    end
end
puts '[+] Running threads'
threads.each{|t|t.join; puts 'Threads done'}

#Do more work here, queue should be fully populated
puts '[+] Writing to file'
File.open('E:/Export.dat', 'wt', encoding: 'UTF-16LE') do |f|
    until queue.empty?
        unit = queue.pop(true) rescue nil
        if unit
            f.puts unit
        end
    end
end

您还需要衡量代码中瓶颈的位置。简单的计时器(开始和结束时间之间的差异)很好。如果元数据的评估需要10毫秒的线程和100毫秒没有,并且写入文件需要1000毫秒。那么你不会注意到多线程的巨大差异。