ruby可以同时运行的线程数有限制吗?

时间:2010-08-22 04:34:53

标签: ruby multithreading

如果不是最大值,同时仍然保持高效?

我正在创建14个线程,每个线程打开一个URL列表(大约500个),为每个线程创建一个新线程,然后下载它,并将其添加到MySQL数据库。 MySQL池大小设置为50。

这是RoR中的rake任务。

使用Kernal#fork或其他方法会更好吗?

3 个答案:

答案 0 :(得分:12)

require 'open-uri'
a = 'http://www.example.com ' * 30
arr = a.split(' ')

arr.each_slice(3) do |group|
  group.map do |site|
    Thread.new do
      open(site)
      p 'finished'
    end
  end.each(&:join)
end

答案 1 :(得分:3)

使用Ruby 1.8,它实际上仅限于你拥有多少内存。您可以为每个进程创建数万个线程。 Ruby解释器处理线程的管理,只创建一个或两个本机线程。 CPU不在线程之间切换,这不是真正的多任务处理。

Ruby 1.9使用本机线程。限制似乎是操作系统允许的限制。仅仅是为了测试,我可以在操作系统不再允许的情况下使用Ruby 1.9在我的mac上创建超过2000个线程。

请注意,拥有数千个进程的线程并不是一个好主意。在此之前,线程调度成为一种负担。

答案 2 :(得分:3)

好吧,既然你的线程将是IO绑定的,那么好消息是Ruby 1.8和1.9线程都适用于此。 Ruby 1.8使用“用户空间线程”,这意味着在Ruby中创建新线程时不会创建真正的新OS线程。这对CPU多任务处理很不利,因为一次只有一个Ruby线程实际运行,但对多任务处理有利。 Ruby 1.9使用真正的线程,对两者都有好处。

您可以创建的线程数取决于您的系统。当然有实际的限制,但你可能不希望靠近它们。首先,除非您所关注的服务器非常慢并且连接速度非常快,否则只需几个线程即可使您的Internet连接饱和。此外,如果你从一台服务器上抓取了很多页面,那么从500个线程中同时抛出500个请求也不会有任何好处。

我开始很小:一次运行10或20个线程。根据服务器负载,带宽等增加或减少这一点。还存在与MySQL数据库并发连接的问题。根据表的设置方式和表的大小,尝试同时插入太多数据并不会很好。