【问题标题】:How to run multiple threads at the same time in ruby while working with a file?如何在处理文件时在 ruby​​ 中同时运行多个线程?
【发布时间】:2011-11-30 00:02:31
【问题描述】:

我今天一直在玩弄 Ruby 和线程。我有一个要检查的代理列表。如果我编写如下内容,假设通过一个非常大的代理列表需要 10 秒的超时时间将花费数小时:

  proxies.each do |proxy|
   check_proxy(proxy)
  end

我试图找出线程的第一个问题是如何同时启动多个线程。我在网上找到了一段简洁的小sn-p代码:

for page in pages
  threads << Thread.new(page) { |myPage|

    puts "Fetching: #{myPage}\n"
    doc = Hpricot(open(myPage.to_s)).to_s
    puts "Got #{myPage}:  #{doc.size}"
  }
end

就同时启动它们而言,似乎工作得很好。所以现在我可以...开始同时检查所有 7000 条记录?

我如何去一个文件,为每个线程取出一行,运行一批像 20 并重复这个过程?

我可以运行一个 while 循环来同时启动 20 个线程(从文件中删除行)并一直运行直到文件为空白?

我对我应该做的事情的逻辑有点薄弱。

谢谢大家!

PS。

另一个想法:如果 20 名工人不断地随意弄乱文件,会不会出现文件访问问题?如果是这样,有什么好的方法可以解决这个问题?

【问题讨论】:

    标签: ruby windows multithreading


    【解决方案1】:

    您要查找的关键字是threadpool。你可以尝试为 Ruby 找到一个(我相信至少在 Github 上有一对),或者自己动手。

    Here's 在 SO 上的一个简单实现。

    Re:文件访问,IMO 你不应该让工作人员直接修改文件,而是在你的主线程中进行。您不想在那里允许同时进行编辑。

    【讨论】:

    • 要在主线程中进行文件修改,您应该让工作人员将值返回到主线程,然后让主线程进行编辑,对吧?
    • 我想是的。或者让线程编辑它,但我猜想使用互斥锁来确保独家编辑权。
    【解决方案2】:

    尝试使用gem DelayJob: https://github.com/tobi/delayed_job

    【讨论】:

      【解决方案3】:

      您不需要生成那么多线程来完成这项工作。事实上,生成大量线程会降低应用程序的整体性能。如果您以异步方式检查每个代理而不阻塞,则可以使用更少的线程。

      您将创建一个文件管理器线程来处理该文件。每行都作为请求添加到数组(请求队列)。在请求队列的另一端,您可以使用eventmachine 发送请求而不会阻塞。 eventmachine 也将用于接收响应并处理超时。然后可以将响应放置在文件管理器线程轮询的另一个数组(响应队列)上。文件管理器线程从响应队列中提取响应并解析代理是否存在。

      这让您只需创建两个线程。您将遇到的一个问题是限制已发送的请求数量,因为此模型将能够在不到一秒的时间内发送所有请求并淹没最近的路由器。根据我的经验,您应该能够在任何时候处理大约 500 个未完成的请求。

      有不止一种方法可以异步解决这个问题,但希望以上内容足以帮助您开始使用非阻塞 I/O。

      【讨论】:

      • 我在想你可能会因为仅仅使用数组作为队列而遇到线程安全问题。 stdlib 中有一个 Queue 类,您可以使用它来代替。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多