在Ruby中,我们可以通过线程类创建多线程,Ruby的线程很轻,可以有效地实现并行代码,多线程在一个程序中同时运行以完成不同的任务称为多线程,本文是武林技术频道小编和大家分享的讲解Ruby编程中的多线程。
创建 Ruby 线程
要启动一个新的线程,只需要调用 Thread.new 即可:
ruby;"># 线程 #1 代码部分Thread.new { # 线程 #2 执行代码}# 线程 #1 执行代码
实例
以下实例展示了如何在Ruby程序中使用多线程:
#!/usr/bin/ruby def func1 i=0 while i<=2 puts "func1 at: #{Time.now}" sleep(2) i=i+1 endend def func2 j=0 while j<=2 puts "func2 at: #{Time.now}" sleep(1) j=j+1 endend puts "Started At #{Time.now}"t1=Thread.new{func1()}t2=Thread.new{func2()}t1.joint2.joinputs "End at #{Time.now}"
以上代码执行结果为:
Started At Wed May 14 08:21:54 -0700 2014func1 at: Wed May 14 08:21:54 -0700 2014func2 at: Wed May 14 08:21:54 -0700 2014func2 at: Wed May 14 08:21:55 -0700 2014func1 at: Wed May 14 08:21:56 -0700 2014func2 at: Wed May 14 08:21:56 -0700 2014func1 at: Wed May 14 08:21:58 -0700 2014End at Wed May 14 08:22:00 -0700 2014
线程生命周期
1、线程的创建可以使用Thread.new,同样可以以同样的语法使用Thread.start 或者Thread.fork这三个方法来创建线程。
2、创建线程后无需启动,线程会自动执行。
3、Thread 类定义了一些方法来操控线程。线程执行Thread.new中的代码块。
4、线程代码块中最后一个语句是线程的值,可以通过线程的方法来调用,如果线程执行完毕,则返回线程值,否则不返回值直到线程执行完毕。
5、Thread.current 方法返回表示当前线程的对象。 Thread.main 方法返回主线程。
6、通过 Thread.Join 方法来执行线程,这个方法会挂起主线程,直到当前线程执行完毕。
线程状态
线程有5种状态:
线程和异常
当某线程发生异常,且没有被rescue捕捉到时,该线程通常会被无警告地终止。但是,若有其它线程因为Thread#join的关系一直等待该线程的话,则等待的线程同样会被引发相同的异常。
begin t = Thread.new do Thread.pass # 主线程确实在等join raise "unhandled exception" end t.joinrescue p $! # => "unhandled exception"end
使用下列3个方法,就可以让解释器在某个线程因异常而终止时中断运行。
当使用上述3种方法之一后,整个解释器就会被中断。
t = Thread.new { ... }t.abort_on_exception = true
线程同步控制
在Ruby中,提供三种实现同步的方式,分别是:
1. 通过Mutex类实现线程同步
2. 监管数据交接的Queue类实现线程同步
3. 使用ConditionVariable实现同步控制
通过Mutex类实现线程同步
通过Mutex类实现线程同步控制,如果在多个线程钟同时需要一个程序变量,可以将这个变量部分使用lock锁定。 代码如下:
#encoding:gbkrequire "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.unlockend ticket1=Thread.new 10 do 10.times do |value| ticketNum=15 buyTicket(ticketNum) sleep 0.01 endend ticket2=Thread.new 10 do 10.times do |value| ticketNum=20 buyTicket(ticketNum) sleep 0.01 endend sleep 1ticket1.jointicket2.join
输出结果如下:
Synchronize Threadyou have successfully bought 15 ticketsyou have successfully bought 20 ticketsyou have successfully bought 15 ticketsyou have successfully bought 20 ticketsyou have successfully bought 15 ticketsyou have successfully bought 20 ticketsyou have successfully bought 15 ticketsyou have successfully bought 20 ticketsyou have successfully bought 15 ticketsyou have successfully bought 20 ticketsyou have successfully bought 15 ticketssorry,no enough ticketssorry,no enough ticketssorry,no enough ticketssorry,no enough ticketssorry,no enough ticketssorry,no enough ticketssorry,no enough ticketssorry,no enough ticketssorry,no enough tickets
除了使用lock锁定变量,还可以使用try_lock锁定变量,还可以使用Mutex.synchronize同步对某一个变量的访问。
监管数据交接的Queue类实现线程同步
Queue类就是表示一个支持线程的队列,能够同步对队列末尾进行访问。不同的线程可以使用统一个对类,但是不用担心这个队列中的数据是否能够同步,另外使用SizedQueue类能够限制队列的长度
SizedQueue类能够非常便捷的帮助我们开发线程同步的应用程序,应为只要加入到这个队列中,就不用关心线程的同步问题。
经典的生产者消费者问题:
#encoding:gbkrequire "thread"puts "SizedQuee Test" queue = Queue.new producer = Thread.new do 10.times do |i| sleep rand(i) # 让线程睡眠一段时间 queue << i puts "#{i} produced" endend consumer = Thread.new do 10.times do |i| value = queue.pop sleep rand(i/2) puts "consumed #{value}" endend consumer.join程序的输出:SizedQuee Test0 produced1 producedconsumed 02 producedconsumed 1consumed 23 producedconsumed 34 produced consumed 45 producedconsumed 56 producedconsumed 67 producedconsumed 78 produced9 producedconsumed 8consumed 9
使用ConditionVariable实现同步控制
使用 ConditonVariable进行同步控制,能够在一些致命的资源竞争部分挂起线程直到有可用的资源为止。
#encoding:gbkrequire "thread"puts "thread synchronize by ConditionVariable" mutex = Mutex.newresource = ConditionVariable.new a = Thread.new { mutex.synchronize { # 这个线程目前需要resource这个资源 resource.wait(mutex) puts "get resource" }} b = Thread.new { mutex.synchronize { #线程b完成对resourece资源的使用并释放resource resource.signal }} a.joinputs "complete"
mutex 是声明的一个资源,然后通过ConditionVariable来控制申请和释放这个资源。
b 线程完成了某些工作之后释放资源resource.signal,这样a线程就可以获得一个mutex资源然后进行执行。 执行结果:
thread synchronize by ConditionVariableget resourcecomplete
线程类方法
完整的 Thread(线程) 类方法如下:
线程实例化方法
以下实例调用了线程实例化方法 join:
#!/usr/bin/ruby thr = Thread.new do # 实例化 puts "In second thread" raise "Raise exception"endthr.join # 调用实例化方法 join
以下是完整实例化方法列表:
线程实例化方法
以下实例调用了线程实例化方法 join:
#!/usr/bin/ruby thr = Thread.new do # 实例化 puts "In second thread" raise "Raise exception"endthr.join # 调用实例化方法 join
以下是完整实例化方法列表:
通过以上的介绍,相信大家已经明了讲解Ruby编程中的多线程,不过在实际操作的时候,程序员一定要谨慎,选择武林技术频道网进行学习,会让您受益匪浅哦!
新闻热点
疑难解答
图片精选