加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Ruby并发I / O.

发布时间:2020-12-17 03:31:22 所属栏目:百科 来源:网络整理
导读:按照此, Ruby thread limit – Also for any language 我试图理解为什么我的线程不起作用. 一些答案非常明确,如: “..使用fork创建4个子进程将利用您的4个核心” 这将是我最后的方法,因为线程在我的情况下似乎不起作用. 这个: “..Ruby MRI线程本身并不能
按照此,
Ruby thread limit – Also for any language

我试图理解为什么我的线程不起作用.
一些答案非常明确,如:

“..使用fork创建4个子进程将利用您的4个核心”
这将是我最后的方法,因为线程在我的情况下似乎不起作用.

这个:

“..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)

第一个块(顺序)运行do_stuff 4次,一个接一个,第二个块(子进程)运行在4个核心上,而第三个块(线程)运行在1个核心上.

如果您将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.
  

  

Do I really need to spawn processes to see real parallelism in ruby?

0 ( 1.013693) thread 0.000000 0.000000 0.000000 ( 1.003463)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读