Ruby 教程 之 Ruby 多线程 4
Ruby 多线程
每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。
线程是程序中一个单一的顺序控制流程,在单个程序中同时运行多个线程完成不同的工作,称为多线程。
Ruby 中我们可以通过 Thread 类来创建多线程,Ruby的线程是一个轻量级的,可以以高效的方式来实现并行的代码。
线程和异常
当某线程发生异常,且没有被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
线程同步控制
在Ruby中,提供三种实现同步的方式,分别是:
通过Mutex类实现线程同步
监管数据交接的Queue类实现线程同步
使用ConditionVariable实现同步控制
通过Mutex类实现线程同步
通过Mutex类实现线程同步控制,如果在多个线程钟同时需要一个程序变量,可以将这个变量部分使用lock锁定。 代码如下:
实例
!/usr/bin/ruby
require "thread"
puts "Synchronize Thread"
@num=200
@mutex=Mutex.new
def buyTicket(num)
@mutex.lock
if @num>=num
@num=@num-num
puts "you have successfully bought #{num} tickets"
else
puts "sorry,no enough tickets"
end
@mutex.unlock
end
ticket1=Thread.new 10 do
10.times do |value|
ticketNum=15
buyTicket(ticketNum)
sleep 0.01
end
end
ticket2=Thread.new 10 do
10.times do |value|
ticketNum=20
buyTicket(ticketNum)
sleep 0.01
end
end
sleep 1
ticket1.join
ticket2.join
尝试一下 »
以上代码执行结果为:
Synchronize Thread
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
除了使用lock锁定变量,还可以使用try_lock锁定变量,还可以使用Mutex.synchronize同步对某一个变量的访问。