📜  红宝石 |线程生命周期及其状态

📅  最后修改于: 2022-05-13 01:54:32.827000             🧑  作者: Mango

红宝石 |线程生命周期及其状态

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

线程状态

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

  1. Runnable:当前正在运行或准备好在可用时占用 CPU 资源的线程。
  2. Sleeping:当前正在休眠的线程,或者正在等待 IO,或者自己停止的线程。
  3. Aborting:这是一个中间状态。已被杀死但尚未终止的中止线程。
  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

下表显示了状态的名称及其返回值:

StatesReturn Value
Runnablerun
Sleepingsleep
Abortingaborting
Terminated normallyfalse
Terminated with exceptionnil

主线程

在 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  

输出:

说明:这个程序显示了主线程是如何执行的。首先,我们创建主线程,然后在这个主线程中有两个子线程,即a1a2线程。当线程a1完全执行时,然后终止a1线程并将执行传递给a2线程。之后杀死a2线程并打印主线程中存在的线程列表及其状态。当主线程中存在的所有线程都死了,那么主线程就存在了。

备用线程状态:暂停、唤醒和终止

正如我们所知,线程是在可运行状态下创建并准备好运行的。线程通过进入睡眠状态、调用Thread.stop方法或调用Kernel.sleep来暂停自身。没有线程可以被另一个线程强行暂停。如果一个线程在没有参数的情况下调用Kernel.sleep ,那么它会永远暂停线程或直到被唤醒,如果一个线程用一个参数调用Kernel.sleep ,那么它会暂时将线程置于睡眠状态。当给定时间到期时,处于临时睡眠状态的线程会自动唤醒并重新进入可运行状态。

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

一个线程可以通过调用实例方法kill来强制终止其他线程。终止和退出方法类似于 kill 方法。这些方法将被杀死的方法置于正常终止状态。除非您有办法知道线程未处于文件共享状态的中间,否则终止线程是危险的事情。用 ! 杀死一个线程方法更有害,因为被杀死的线程可能会使套接字、文件和其他资源保持打开状态。