Ruby 线程的生命周期及其状态

Ruby 线程的生命周期及其状态

线程的生命周期提供了线程从出生到结束的简要描述。一个新的线程可以在 Thread.newThread.start ,或 Thread.fork 方法的帮助下被创建。创建后不需要启动一个新的线程。当CPU的资源可用时,一个线程就会自动开始运行。Thread.new的引用值是一个Thread对象。Thread类提供了各种方法来查询和操作线程。
一个线程运行到与调用Thread.new有关的代码块中,然后停止运行。线程块中最后一个表达式的值就是该线程的值,该值是通过调用Thread对象的value方法获得的。只有当线程完全运行后,value方法才会返回值,否则它不会向完全运行的线程返回值。如果线程中出现了异常,那么它就会终止运行中的线程。这个条件只对那些不是主线程的线程起作用,而且只有那些包含异常的线程才会终止。

线程状态

在Ruby中,线程有五种状态,显示线程的状态。你可以使用 alive?status 方法来检查线程的状态。

  1. 可运行的:当前正在运行的线程,或准备在CPU资源可用时占用其资源的线程。
  2. 休眠: 当前正在休眠的线程,或者正在等待IO的线程,或者本身已经停止的线程。
  3. 中止:是一种中间状态。一个中止的线程,它已经被杀死,但还没有终止。
  4. 异常终止:一个包含异常的线程,或者换句话说,一个由于异常的出现而被终止的线程。
  5. 正常终止:正常终止的线程,或不包含异常并完成其工作的线程。

示例:

# Ruby program to illustrate 
# check status of thread
  
counter = 0
   
# creating new thread
x = Thread.new { loop { counter += 1 } }
  
# check thread alive or not
puts x.alive? 

输出:

true

线程的生命周期及其状态

下表显示了状态的名称和它们的返回值。

状态 返回值
可运行 运行
睡眠状态 睡眠
中止 中止
正常终止 错误
异常终止 nil

主线程

在Ruby中,主线程是多线程的一个特殊部分。它是一个程序的最顶层线程,所有的子线程都在这个线程下运行,或者换句话说,它是父线程,同一程序的其他线程是主线程的子线程。主线程是在main方法的帮助下创建的。当主线程的工作完成后,Ruby解释器就会停止运行,这意味着主线程和子线程完成了它们的任务。类方法Thread.main返回代表主线程的Thread对象。如果在主线程中出现了异常,并且没有在任何地方得到处理,那么Ruby解释器会打印一条消息或退出。如果在主线程以外的其他线程中出现了异常,那么Ruby解释器将终止包含异常的线程。

例子

# Ruby program to illustrate 
# main thread
  
# Create main thread
puts Thread.main  
puts ""  
  
# create new thread 
a1 = Thread.new {sleep 200}  
list_thread= Thread.list
list_thread.each {|t| p t }  
puts "Current thread = " + Thread.current.to_s  
  
 # create new thread
a2 = Thread.new {sleep 200}  
list_thread= Thread.list
list_thread.each {|t| p t }  
puts "Current thread=" + Thread.current.to_s   
  
 # kill thread a1
Thread.kill(a1) 
  
# pass execution to thread a2 
Thread.pass   
  
# kill thread a2                         
Thread.kill(a2)          
  
list_thread= Thread.list
list_thread.each {|t| p t }  
    
# exit main thread
Thread.exit  

输出

#<Thread:0x00000001afe1b8>

#<Thread:0x00000001afe1b8 run>  
#<Thread:0x00000001d05c68@/var/www/service/usercode/1749234900/source.rb:9 sleep>  
Current thread = #<Thread:0x00000001afe1b8>  
#<Thread:0x00000001afe1b8 run>  
#<Thread:0x00000001d05c68@/var/www/service/usercode/1749234900/source.rb:9 sleep>  
#<Thread:0x00000001c8bd50@/var/www/service/usercode/1749234900/source.rb:15 run>  
Current thread=#<Thread:0x00000001afe1b8>  
#<Thread:0x00000001afe1b8 run>  
#<Thread:0x00000001c8bd50@/var/www/service/usercode/1749234900/source.rb:15 dead>

解释: 这个程序显示了主线程是如何执行的。首先,我们创建了一个主线程,然后在这个主线程中,有两个子线程,即a1和a2。当线程a1完全执行时,就杀死a1线程,并将执行任务交给a2线程。之后,杀死a2线程,并打印主线程中存在的线程列表和它们的状态。当所有存在于主线程中的线程都死了,那么主线程就存在了。

替代线程状态。暂停、唤醒和杀戮

我们知道,线程是在可运行状态下创建的,并准备运行。一个线程通过进入睡眠状态,或通过调用Thread.stop方法,或通过调用Kernel.sleep来暂停自己。任何线程都不能被其他线程强行暂停。如果一个线程在调用Kernel.sleep时没有任何参数,那么它将永远暂停该线程,直到被唤醒;如果一个线程在调用Kernel.sleep时有一个参数,那么它将暂时使该线程进入睡眠状态。处于临时睡眠状态的线程在给定的时间过后会自动醒来,并重新进入可运行状态。

一个通过调用Thread.stop或调用kernel.sleep暂停的线程可以通过调用实例方法再次启动,即唤醒和运行。这些方法将一个线程的状态从睡眠状态切换到可运行状态。运行方法也会调用线程调度器。由于调用了线程调度器,最近被唤醒的线程可能会获得CPU资源。wakeup方法在不调用线程调度器的情况下唤醒了特定的线程。

一个线程可以通过调用实例方法kill强行终止其他线程。终止和退出方法与kill方法类似。这些方法将被杀的方法放入正常终止状态。杀死一个线程是很危险的事情,除非你有办法知道该线程不在文件共享状态中。用!方法杀死一个线程是更有害的,因为一个被杀死的线程可能会使套接字、文件和其他资源开放。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程