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_Threadpool - Fatal编程技术网

Ruby 如何限制并发线程的数量

Ruby 如何限制并发线程的数量,ruby,multithreading,threadpool,Ruby,Multithreading,Threadpool,在视频URL中,有数千个视频可供下载。我想使用线程来完成这项工作,但一次最多只能使用十个线程。我如何重写下面的代码来获得它 VIDEO_URL.each do | video | @workers << Thread.new{dl_video(video)} end @workers.each { |t| t.join } 你可以用 您试图实现的是一种常用的模式,称为线程池 我还没有尝试过,但也许gem或类似的东西值得研究: require "threadpool" pool

在视频URL中,有数千个视频可供下载。我想使用线程来完成这项工作,但一次最多只能使用十个线程。我如何重写下面的代码来获得它

VIDEO_URL.each do | video |
  @workers << Thread.new{dl_video(video)}
end
@workers.each { |t| t.join }
你可以用


您试图实现的是一种常用的模式,称为线程池

我还没有尝试过,但也许gem或类似的东西值得研究:

require "threadpool"

pool = ThreadPool.new(10)
VIDEO_URL.each{|video| pool.process{dl_video(video)}}

您需要的是一个线程池。Ruby的线程有一个新的应用程序,其中包括这个功能

未经测试的代码段直接改编自库示例:

require 'thread/pool'

# Create thread pool with up to 10 simultaneous running threads 
pool = Thread.pool(10)

VIDEO_URL.each do | video |
  # Add each download task the the thread pool
  pool.process do 
    dl_video(video)
  end
end

# Block and wait for the thread pool to run out of tasks
pool.shutdown

一个不涉及任何新gems的简单解决方案是启动10个线程,弹出并处理数组中的第一个URL

[].tap do |threads|
  urls = VIDEO_URLS.clone
  semaphore = Mutex.new
  number_of_threads = 10

  number_of_threads.times do
    threads << Thread.new do
      until urls.empty?        
        url = semaphore.synchronize { urls.pop }
        download_video(url)
      end
    end
  end
end.each(&:join)

这种方法将创建多达十个同步下载,等待所有十个下载完成,然后创建多达十个新线程,等待它们完成,依此类推。这可能不是最优的:我同意你的观点,这不是最好的方法。@ibr在工作线程超过10个之后,gem线程池似乎没有被阻塞,使线程池的I/O阻塞是否无效?很抱歉,我不理解你的问题。嗨,我更新了我的描述,我的意思是,如果我把任务放在线程池中,视频就不会被下载。我想你使用的是刚才提到的gem sawa,而不是我使用的那个。我已经在我的回复和pool.shutdown块中测试了代码。很好。感谢您的帮助,gem threadpool在工作线程超过10个之后似乎没有被阻塞,是I/O块使线程池无效吗?您的第一个示例是一个非常小的线程池实现:-是的。基本上,与线程池相同,但不添加任何额外的宝石。编辑:我注意到我帖子中的错误。它说不涉及线程池,而本应不涉及线程池宝石。更正:
require 'thread/pool'

# Create thread pool with up to 10 simultaneous running threads 
pool = Thread.pool(10)

VIDEO_URL.each do | video |
  # Add each download task the the thread pool
  pool.process do 
    dl_video(video)
  end
end

# Block and wait for the thread pool to run out of tasks
pool.shutdown
[].tap do |threads|
  urls = VIDEO_URLS.clone
  semaphore = Mutex.new
  number_of_threads = 10

  number_of_threads.times do
    threads << Thread.new do
      until urls.empty?        
        url = semaphore.synchronize { urls.pop }
        download_video(url)
      end
    end
  end
end.each(&:join)
[].tap do |threads|
  slices # split VIDEO_URLS into required slices. leave this up to you.
  slices.each do |urls|
    threads << Thread.new do
      urls.each { |url| download_video(url) }
    end
  end
end.each(&:join)