Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby线程限制-也适用于任何语言_Ruby_Multithreading - Fatal编程技术网

Ruby线程限制-也适用于任何语言

Ruby线程限制-也适用于任何语言,ruby,multithreading,Ruby,Multithreading,我正试图用Ruby尽可能快地处理1000帧。因此,我目前启动了1000个线程(每帧一个)。结果很糟糕。它使用了大量内存,而且速度很慢。我的CPU是这个 它说它支持4个线程。(我猜每个CPU 2个?)。 因此,如果我一次启动4个Ruby线程,等待它们完成,然后再启动4个等等,那么完成处理将需要250个“步骤”,而不是1000个 编辑:我的代码现在: beginning_time = Time.now limit=1 for frame_index in 1..limit greys

我正试图用Ruby尽可能快地处理1000帧。因此,我目前启动了1000个线程(每帧一个)。结果很糟糕。它使用了大量内存,而且速度很慢。我的CPU是这个 它说它支持4个线程。(我猜每个CPU 2个?)。 因此,如果我一次启动4个Ruby线程,等待它们完成,然后再启动4个等等,那么完成处理将需要250个“步骤”,而不是1000个

编辑:我的代码现在:

beginning_time = Time.now
    limit=1
for frame_index in 1..limit
    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)
        img_processor.greyscale_image
        img_processor.save_image_in_dir(output_dir,"frame_%04d"%+frame_number)
        puts "Greyscaled Image #{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"
start\u time=time.now
极限=1
对于1.限制中的帧索引

greyscale_frames_threads例如,您可以使用该类创建线程池并安排您的工作:

class Pool
  def initialize(size)
    @size = size
    @jobs = Queue.new
    @pool = Array.new(@size) do |i|
      Thread.new do
        Thread.current[:id] = i
        catch(:exit) do
          loop do
            job, args = @jobs.pop
            job.call(*args)
          end
        end
      end
    end
  end

  def schedule(*args, &block)
    @jobs << [block, args]
  end

  def shutdown
    @size.times do
      schedule { throw :exit }
    end
    @pool.map(&:join)
  end
end

这意味着(在本例中)最多会有32个线程,每个线程都会弹出一些您计划的工作。

在标准ruby解释器中,一次只能运行一个线程,因此如果您是计算绑定的,添加线程没有帮助。如果你搜索GIL或GVL(全局解释器锁),你会发现很多关于这个主题的文章。如果您是IO绑定的,那么等待IO的线程将放弃控制,所以线程在这种情况下仍然有用

C扩展也可以放弃GVL,因此有多个线程并行运行,但是这只在ruby 1.9.3+上才可能,编写C扩展时需要考虑到这一点

如果计算并行性对您很重要,那么您可能想看看jruby或rubinius,它们都没有GVL。在这两者中,jruby更为成熟


最后,为每个任务创建一个线程是浪费的-这涉及到一定的开销,因此通常的模式是拥有一个可重用的工作线程池。

编写一个允许您改变线程数量的测试实用程序怎么样。我不喜欢测试,我也不想浪费时间做测试。用语言A来测试语言A是没有意义的。理论上这是不可能的。而且我不能真正测试它,因为如果我同时运行两个测试,一个将创建1000个线程,另一个将创建4。。因此,我只是让事情变得更糟。我不是建议比较语言A和语言B,而是建议使用
ruby
编写一个实用程序,它允许您使用不同数量的线程检查性能。它仍然需要1000个“步骤”,但这项工作是并行完成的。我已经编辑了我的问题。请看一看克里斯托夫的答案是错的?在任何方面,我都不能用纯Ruby并行运行线程?因此,如果GVL存在,我不理解在Ruby中使用线程的意义Kristoff的答案没有错,这取决于线程所做的工作类型。若它们主要做IO、数据库查询或调用选择退出GVL的c扩展,那个么它们的并行化就很好了。如果他们不这样做,那么在标准ruby上,您一次只能使用一个CPU核,ruby有许多不同的实现。只有极少数有GVL。大多数实现都完全能够并行运行线程。是的,但根据@Frederick的回答,这不会并行运行它们?@Trt-Trt:线程将尽Ruby所能并行运行。对于Ruby MRI版本(包括1.9.3和2.0.0),这意味着他们将分时共享一个CPU核心。值得注意的是,这是许多系统中线程的正常状态——直到几年前,PC CPU只有一个内核,所有线程都是分时的。默认情况下,PC机上真正的并行线程技术只有十年左右的历史(例如,2006年英特尔酷睿双核(Intel Core Duo)大张旗鼓地发布)。Ruby并不是唯一一个对它支持有限的人。@TrtTrt如果你想要扩展线程支持,你可能想看看jruby,如果这对你来说是可能的话。然后,您基本上拥有jvm的全部功能,可供您使用。
pool.schedule do 
  # do your stuff
end