Ruby死锁

两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,这种状况,就称为死锁。

例如,一个进程 p1 占用了显示器,同时又必须使用打印机,而打印机被进程 p2 占用,p2 又必须使用显示器,这样就形成了死锁。

当我们在使用 Mutex 对象时需要注意线程死锁。

#!/usr/bin/ruby -w # -*- coding : utf-8 -*- puts "HaiCoder(www.haicoder.net)" require 'thread' mutex = Mutex.new cv = ConditionVariable.new a = Thread.new { mutex.synchronize { puts "A: I have critical section, but will wait for cv" cv.wait(mutex) puts "A: I have critical section again! I rule!" } } puts "(Later, back at the ranch...)" b = Thread.new { mutex.synchronize { puts "B: Now I am critical, but am done with cv" cv.signal puts "B: I am still critical, finishing up" } } a.join b.join

以上实例输出结果为:

07_Ruby多线程.png

线程类方法

完整的 Thread(线程) 类方法如下:

序号 方法描述
1 Thread.abort_on_exception 若其值为真的话,一旦某线程因异常而终止时,整个解释器就会被中断。它的默认值是假,也就是说,在通常情况下,若某线程发生异常且该异常未被Thread#join等检测到时,该线程会被无警告地终止。
2 Thread.abort_on_exception= 如果设置为 true, 一旦某线程因异常而终止时,整个解释器就会被中断。返回新的状态
3 Thread.critical 返回布尔值。
4 Thread.critical= 当其值为true时,将不会进行线程切换。若当前线程挂起(stop)或有信号(signal)干预时,其值将自动变为false。
5 Thread.current 返回当前运行中的线程(当前线程)。
6 Thread.exit 终止当前线程的运行。返回当前线程。若当前线程是唯一的一个线程时,将使用exit(0)来终止它的运行。
7 Thread.fork { block } 与 Thread.new 一样生成线程。
8 Thread.kill( aThread ) 终止线程的运行.
9 Thread.list 返回处于运行状态或挂起状态的活线程的数组。
10 Thread.main 返回主线程。
11 Thread.new( [ arg ]* ) {| args | block } 生成线程,并开始执行。数会被原封不动地传递给块. 这就可以在启动线程的同时,将值传递给该线程所固有的局部变量。
12 Thread.pass 将运行权交给其他线程. 它不会改变运行中的线程的状态,而是将控制权交给其他可运行的线程(显式的线程调度)。
13 Thread.start( [ args ]* ) {| args | block } 生成线程,并开始执行。数会被原封不动地传递给块. 这就可以在启动线程的同时,将值传递给该线程所固有的局部变量。
14 Thread.stop 将当前线程挂起,直到其他线程使用run方法再次唤醒该线程。

线程实例化方法

以下实例调用了线程实例化方法 join:

#!/usr/bin/ruby thr = Thread.new do # 实例化 puts "In second thread" raise "Raise exception" end thr.join # 调用实例化方法 join

以下是完整实例化方法列表:

序号 方法描述
1 thr[ name ] 取出线程内与name相对应的固有数据。 name可以是字符串或符号。 若没有与name相对应的数据时, 返回nil。
2 thr[ name ] = 设置线程内name相对应的固有数据的值, name可以是字符串或符号。 若设为nil时, 将删除该线程内对应数据。
3 thr.abort_on_exception 返回布尔值。
4 thr.abort_on_exception= 若其值为true的话,一旦某线程因异常而终止时,整个解释器就会被中断。
5 thr.alive? 若线程是"活"的,就返回true。
6 thr.exit 终止线程的运行。返回self。
7 thr.join 挂起当前线程,直到self线程终止运行为止. 若self因异常而终止时, 将会当前线程引发同样的异常。
8 thr.key? 若与name相对应的线程固有数据已经被定义的话,就返回true
9 thr.kill 类似于 Thread.exit
10 thr.priority 返回线程的优先度. 优先度的默认值为0. 该值越大则优先度越高.
11 thr.priority= 设定线程的优先度. 也可以将其设定为负数.
12 thr.raise( anException ) 在该线程内强行引发异常.
13 thr.run 重新启动被挂起(stop)的线程. 与wakeup不同的是,它将立即进行线程的切换. 若对死进程使用该方法时, 将引发ThreadError异常.
14 thr.safe_level 返回self 的安全等级. 当前线程的safe_level与$SAFE相同.
15 thr.status 使用字符串"run"、“sleep"或"aborting” 来表示活线程的状态. 若某线程是正常终止的话,就返回false. 若因异常而终止的话,就返回nil。
16 thr.stop? 若线程处于终止状态(dead)或被挂起(stop)时,返回true.
17 thr.value 一直等到self线程终止运行(等同于join)后,返回该线程的块的返回值. 若在线程的运行过程中发生了异常, 就会再次引发该异常.
18 thr.wakeup 把被挂起(stop)的线程的状态改为可执行状态(run), 若对死线程执行该方法时,将会引发ThreadError异常。