新手问题 ruby 线程使用举例

fsword · 发布于 2013年02月06日 · 最后由 luotuo 回复于 2014年06月06日 · 5300 次阅读
244
本帖已被设为精华帖!

这年头,大多数人应该不需要看这些内容了,所以以下也不是什么入门,只是有些同学还不太了解,举几个简单例子帮助理解

例子一:

require 'faraday'

Faraday.get 'http://www.sina.com'
puts 'web get done'
puts 'hello'

sleep 3
puts 'completed.'

很简单,ruby脚本先下载,再依次打印 web get donehellocompleted.

例子二:

require 'faraday'

Thread.new do
  Faraday.get 'http://www.sina.com' 
  puts 'web get done'
end
puts 'hello'

sleep 3
puts 'completed.'

这次有所不同,下载和打印web get done的环节是和打印’completed.'同时发生的,这就是线程的作用——传递给Thread.new的block与后续代码”并行“执行了,我们也可以说,传入的block是异步执行(不会阻碍当前执行序列)

那如何拿到并行的执行结果呢?答案是等待。由于我们有thread对象,等待就是它的一个方法,比如这样:

require 'faraday'

t = Thread.new do
  Faraday.get 'http://www.sina.com' 
  puts 'web get done'
end
t.join
puts 'hello'

脚本执行到thread对象的join方法时,将会等待线程执行结束,然后继续进行。

传入线程的block也有返回值,所以我们还可以这样

require 'faraday'

t = Thread.new do
  Faraday.get 'http://www.sina.com' 
  'web get done'
end
puts 'hello'
puts t.value

与join类似,调用thread的value方法时,系统会等待线程执行结束,然后将block的执行结果返回

共收到 9 条回复
1153

对新手很有用~~

3126

那个这个线程会自动关闭么?还是说根本这个线程是“假”的

244

#2楼 @guyanbiao 执行完了自然就结束(也就是你说的关闭),至于是真是假取决于你对”真“、”假“的定义,如果你指的是是否是操作系统分配的线程,那么不同的ruby vm各有不同,cruby 1.8 是”假“的,cruby1.9、jruby是”真“的

2973

有时困难的时不知到何时使用才是最佳实际哦

681

从来不用 join 的路过。。。

2880

CRuby 1.9 线程是和操作系统线程一一对应的, 也就是去掉了 GIL, 支持多线程了 但是还有 GVL, 线程虽然有了但还是在 VM 中最多只吃一个 CPU

GVL 和 GIL 的区别是, GVL 只要跑到 VM 外面 (例如 C 扩展), 两个线程是可以吃满两个 CPU 的

1031

楼主举的例子不甚恰当, 至少, 对于了解多个线程是如何并行工作, 没有起到引导作用.

我这里提一下线程编程, 个人总结的两点惯例...

  1. 在 t = Thread.new {...} 和 t.join 之间, 通常会存在 同样费时 的逻辑代码.
  2. 因此, 多数情况下, t.join , 写在调用代码的最后一行.

只要满足这两点, Thread 代码块中的代码, 就可以和主线程中的代码 同时执行(具体是并发还是真并行, 依赖于平台), 并且, 主线程如果先完成, 还会等待子线程也完成后, 才会退出.

244

#7楼 @zw963 是的,启动一个线程并join等同于顺序执行,如果是这样可能好理解一些

require 'faraday'

threads = %w{ sina sohu google }.map do |site|
  Thread.new do
    Faraday.get "http://www.#{site}.com"
    puts 'web get done'
  end
end
threads.map &:join
puts 'all page downloaded.'
8766

join 。value 没有其他?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册