Ruby多线程

每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。线程是程序中一个单一的顺序控制流程,在单个程序中同时运行多个线程完成不同的工作,称为多线程。

Ruby 中我们可以通过 Thread 类来创建多线程,Ruby 的线程是一个轻量级的,可以以高效的方式来实现并行的代码。

创建Ruby线程

要启动一个新的线程,只需要调用 Thread.new 即可:

# 线程 #1 代码部分 Thread.new { # 线程 #2 执行代码 } # 线程 #1 执行代码

实例

以下实例展示了如何在 Ruby 程序中使用多线程:

#!/usr/bin/ruby -w # -*- coding : utf-8 -*- puts "HaiCoder(www.haicoder.net)" def func1 i=0 while i<=2 puts "func1 at: #{Time.now}" sleep(2) i=i+1 end end def func2 j=0 while j<=2 puts "func2 at: #{Time.now}" sleep(1) j=j+1 end end puts "Started At #{Time.now}" t1=Thread.new{func1()} t2=Thread.new{func2()} t1.join t2.join puts "End at #{Time.now}"

以上代码执行结果为:

01_Ruby多线程.png

线程生命周期

  1. 线程的创建可以使用 Thread.new,同样可以以同样的语法使用 Thread.start 或者 Thread.fork 这三个方法来创建线程。
  2. 创建线程后无需启动,线程会自动执行。
  3. Thread 类定义了一些方法来操控线程。线程执行 Thread.new 中的代码块。
  4. 线程代码块中最后一个语句是线程的值,可以通过线程的方法来调用,如果线程执行完毕,则返回线程值,否则不返回值直到线程执行完毕。
  5. Thread.current 方法返回表示当前线程的对象。 Thread.main 方法返回主线程。
  6. 通过 Thread.Join 方法来执行线程,这个方法会挂起主线程,直到当前线程执行完毕。

线程状态

线程有 5 种状态:

线程状态 返回值
可执行 run
睡眠 Sleeping
退出 aborting
正常终止 false
发生异常终止 nil

线程和异常

当某线程发生异常,且没有被 rescue 捕捉到时,该线程通常会被无警告地终止。但是,若有其它线程因为 Thread#join 的关系一直等待该线程的话,则等待的线程同样会被引发相同的异常。

begin t = Thread.new do Thread.pass # 主线程确实在等join raise "unhandled exception" end t.join rescue p $! # => "unhandled exception" end

使用下列 3 个方法,就可以让解释器在某个线程因异常而终止时中断运行。

  • 启动脚本时指定 -d 选项,并以调试模时运行。
  • 用 Thread.abort_on_exception 设置标志。
  • 使用 Thread#abort_on_exception 对指定的线程设定标志。

当使用上述 3 种方法之一后,整个解释器就会被中断。

t = Thread.new { ... } t.abort_on_exception = true