在 VIDEO_URL
中,有数千个视频要下载 . 我想使用线程来完成这项工作,但一次最多限制为十个线程 . 我怎么能重写以下代码才能得到它?
VIDEO_URL.each do | video |
@workers << Thread.new{dl_video(video)}
end
@workers.each { |t| t.join }
更新
工作线程超过10后,gem thread pool 似乎没有被阻塞,I / O块是否使线程池无效?
如果我下载没有线程池的视频,它运行良好 .
但是,如果我下载带有线程池的视频,视频将不会被下载,主要线程应该在有10名工作人员时被阻止,但事实并非如此 . (每个视频至少应该有1分钟下载)
MAX_WORKERS = 10
@pool = Thread.pool(MAX_WORKERS)
def dl_video(video)
File.open(video["title"], "wb") do |saved_file|
@pool.process{
saved_file.write open(video["link"], :allow_redirections => :safe).read
# saved_file.write(HTTParty.get(video["link"]).parsed_response)
}
end
end
4 回答
您要实现的是经常使用的模式,它被称为线程池 .
我没有尝试过,但也许threadpool宝石或类似的东西值得研究:
你想要的是一个线程池 . Ruby的线程有一个extension,其中包含此功能 .
未经测试的代码段直接改编自库示例:
一个简单的解决方案(不涉及任何新的宝石)将启动10个线程
pop
并处理您的数组中的第一个URL .另一种解决方案是将阵列分成不同的切片(10个或更少);有不同的方法可以做到这一点 . 之后,每个线程都可以处理每个切片 . 代码可能会更长,但如果你愿意,你可以摆脱
Mutex
.你可以使用each_slice .