1

我有一个包含大量文本文件的文件夹列表。这些文件里面是链接。

使用这些链接中的每一个,我将需要获取一个网页,对其进行解析,并根据其中的内容 - 将 JPG 文件保存到与包含提供链接的文本文件的文件夹名称相对应的文件夹中。

现在要注意的是,其中有很多文本文件,甚至还有更多链接。我在想多线程连接和解析网页的过程可能不是一个坏主意。

所以我会有这样的事情:

directories.each do |directory|

 ... 

 all_files_in_directory.each do |file|

  ...

  all_urls_in_file do |url|

   # check if there's any threads that aren't busy
   # make a thread go out to the url and parse it

  end

 end


end

如果可能的话,我有点不确定如何做到这一点 - 我似乎无法找到一种方法让线程只是挂出,直到我告诉他们 some_method() 执行。就好像一个线程所做的事情是在创建时分配给它的,并且无法更改。

所以基本上我希望脚本能够连接和解析,比如说,5个批次而不是1个批次。

这可行吗?如果可行,你将如何解决这个问题?

4

2 回答 2

2

通常,此类活动是通过将“任务”对象排队到正在等待生产者-消费者“池队列”的线程池来执行的。每个线程永远循环,将任务从队列中拉出并调用任务的虚拟“运行”方法。通常,如果他们愿意,任务可以创建更多任务并将它们提交到池队列。

不同的“任务”类后代可以有一个 run() 方法来做不同的事情,因此,即使线程确实“在做创建时分配给它的事情”——这意味着挂在队列上,然后,当任务可用,在不同的任务中调用不同的覆盖方法。

流量控制,对。制作一个可以保存“批量大小”url的batchURL'任务类。在开始时,创建.. 说.. 100 个并将它们推送到“objectQueue”(一个生产者-消费者队列类,如池队列)。在您的 readline 循环中,弹出一个 batchURL,使用 url 加载它并将其提交到池队列。当池线程处理完一个 batchURL 后,将其推回 objectQueue 以供重用。这对未完成的批处理 URL 设置了上限 - 如果 readLine 尝试将太多的批处理 URL 排队,它会发现 objectQueue 为空,因此会阻塞,直到池回收一些批处理 URL。

如果您使用合理数量的 batchSIze、batchURL 和线程,batchURL 应该会愉快地在 objectQueue/workThead/poolQ​​ueue 循环中循环,以高效且有效的方式将数据从 readLine 传送到工作线程。

于 2012-04-19T22:25:25.313 回答
1

对于并发 http 请求,您应该考虑 eventmachine 和em-http-request 。

于 2012-04-20T01:42:01.867 回答