接着, Ruby thread limit - Also for any language
我想了解为什么我的线程不工作。 一些答案非常明确,例如:
“..使用 fork 创建 4 个子进程将利用您的 4 个核心” 这将是我的 final方法,因为线程在我的情况下似乎不起作用。
还有这个:
"..Ruby MRI 线程本身不会充分利用运行 Ruby 代码的多核 CPU。但这对您来说是否是个问题取决于线程在做什么。如果他们对同一台机器上的其他进程进行长时间运行的 I/O 调用,您将在不需要单独进程的情况下看到好处。线程和多处理作为主题可以变得相当复杂,即使是简单的事情。大多数语言会在开箱即用的简单和困难方面做出一些妥协......”
考虑到第二个,我已经从我的代码中删除了所有处理,只留下了 I/O。
这里是:
beginning_time = Time.now
img_processor.load_image(frames_dir+"/frame_0001.png")
img_processor.load_image(frames_dir+"/frame_0002.png")
end_time = Time.now
puts "Time elapsed #{(end_time - beginning_time)*1000} milliseconds"
beginning_time = Time.now
for frame_index in 1..2
greyscale_frames_threads << Thread.new(frame_index) { |frame_number|
puts "Loading Image #{frame_number}"
img_processor.load_image(frames_dir+"/frame_%04d.png"%+frame_number)
}
end
puts "Joining Threads"
greyscale_frames_threads.each { |thread| thread.join } #this blocks the main thread
end_time = Time.now
puts "Time elapsed #{(end_time - beginning_time)*1000} milliseconds"
我得到的是这个......
对于第一个非线程的情况:
Time elapsed 15561.358 milliseconds
对于第二种线程情况:
Time elapsed 15442.401 milliseconds
好的,性能提升在哪里?我错过了什么吗? 硬盘是否阻塞? 我真的需要生成进程才能在 ruby 中看到真正的并行性吗?
最佳答案
Do I really need to spawn processes to see real parallelism in ruby?
是的,我想是的:
require 'timeout'
require 'digest'
require 'benchmark'
def do_stuff
Digest::SHA256.new.digest "a" * 100_000_000
end
N = 10
Benchmark.bm(10) do |x|
x.report("sequential") do
N.times do
do_stuff
end
end
x.report("subprocess") do
N.times do
fork { do_stuff }
end
Process.waitall
end
x.report("thread") do
threads = []
N.times do
threads << Thread.new { do_stuff }
end
threads.each(&:join)
end
end
MRI 2.0.0 的结果:
user system total real
sequential 3.200000 0.180000 3.380000 ( 3.383322)
subprocess 0.000000 0.000000 6.600000 ( 1.068517)
thread 3.290000 0.210000 3.500000 ( 3.496207)
第一个 block (顺序)运行 do_stuff
4 次,一个接一个,第二个 block (子进程)在 4 个内核上运行,而第三个 block (线程)在一个内核上运行。
如果将 do_stuff
更改为:
def do_stuff
sleep(1)
end
结果不同:
user system total real
sequential 0.000000 0.000000 0.000000 ( 10.021893)
subprocess 0.000000 0.010000 0.080000 ( 1.013693)
thread 0.000000 0.000000 0.000000 ( 1.003463)
关于Ruby 并发 I/O,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17191072/