为什么这样跑就像没有线程?

我正在写一个脚本,将ping我的ip范围。 以下是我到目前为止:

lines = `ipconfig`.split("\n") thr = [] ip_line = lines.detect { |l| l=~/Ip Address/i } matcher = /\d+\.\d+\.\d+\.\d+/.match(ip_line) if matcher.length > 0 address = matcher[0] address.sub!(/\.\d+$/,"") (1 .. 254).each do |i| xaddr = address + "." + i.to_s puts "pinging #{xaddr}" thr << Thread.new { `ping #{xaddr}` } end thr.each do |t| t.join output = t.value puts output end end 

事情是,这执行非常缓慢。 像应用程序没有线程。 这是为什么? 我注意到如果我inheritance了Thread,整个事情运行得非常快。 怎么了? 不是线程直接使用?

    Ruby线程由Ruby解释器控制。 到操作系统,Ruby解释器仍然只是一个进程(就像任何其他进程一样)。 Ruby解释器将一个进程拆分成多个ruby线程。

     `ping #{xaddr}` 

    这一行强制Ruby解释器暂时放弃其控制,因为您要求操作系统执行另一个进程。 直到“ping”结束之后,Ruby解释器才会重新获得控制权。 这可能是代码很慢的原因。

    你可以像这样使用IO.popen

     thr << Thread.new xaddr do |adr| IO.popen "ping #{adr}" do |io| io.each {|l| puts l} end end 

    这样,即使使用绿色线程,也可以获得更多的并发性。 原因是解释器不必等到完整的ping输出发送完毕。

    你在运行什么Ruby实现? 在标准Ruby中,线程是“绿色线程”,即不是真正的操作系统线程,而是由Ruby运行时提供的。

    在JRuby中,线程是真正的操作系统线程,因为这是JVM如何实现它们的。

    所以,你可能会看到Ruby的不同实现之间线程性能的差异。 请注意,尽管Ruby 1.9比JRuby(至少在某些基准测试中)要快,但JRuby被认为比Ruby 1.8.6更快。

    嗯,似乎我得到相同的性能

     `...` 

     IO.popen ... 

    是一样的: http : //gist.github.com/511599

    我疯了吗?