线程表示轻量级的子进程。 它是一个单独的执行路径。 在Ruby中,程序的不同部分可以通过使用多个进程在不同程序之间使用多个线程执行,或拆分程序中的任务来同时运行。
Ruby中的线程是并发编程模型的实现。
Ruby多线程
一般情况下,一个正常的程序的执行路径是单线执行。 按编码的顺序执行程序中的所有语句。
但是在多线程程序中,可以按多个路径多个执行程序。 多线程使用较少的内存空间并共享相同的地址空间。 多线程用于一次执行多个任务。
使用thread.new
调用创建一个新线程。它与主线程的执行不同。
线程初始化
要创建一个新的线程Ruby提供了三个关键字,即::new
,::start
和::fork
。
要启动新线程,请将一个代码块调用Thread.new
,Thread.start
或Thread.fork
相关联。这样线程将被创建,新的线程在块退出时退出。
语法:
# Original thread runs
Thread.new {
# New thread is created.
}
# Original thread runs
线程终止
在Ruby中终止一个线程有不同的方法。 要退出给定的线程,使用类名 ::kill
方法。
语法:
thr = Thread.new { ... }
Thread.kill(thr)
Ruby线程实例
#!/usr/bin/ruby
# file : thread-example.rb
th = Thread.new do #Here we start a new thread
Thread.current['counter']=0
5.times do |i| #loop starts and increases i each time
Thread.current['counter']=i
sleep 1
end
return nil
end
while th['counter'].to_i < 4 do
=begin
th is the long running thread
and we can access the same variable
from inside the thread here
=end
puts "Counter is #{th['counter']}"
sleep 0.5
end
puts "Long running process finished!"
执行上面代码,输出以下结果 -
F:\worksp\ruby>ruby thread-example.rb
Counter is
Counter is 0
Counter is 1
Counter is 1
Counter is 2
Counter is 2
Counter is 3
Counter is 3
Long running process finished!
F:\worksp\ruby>
线程生命周期
线程创建完成后,无需启动线程。 它获得正确的CPU资源后自动运行。 块中的最后一个表达式是线程的值。 如果线程完全运行,则value
方法返回线程值,否则,value
方法阻塞,并在线程完成时返回。 线程类在运行查询和操作线程时定义了一些方法。
通过调用线程的Thread.join
方法,可以等待一个特定的线程完成。
线程异常处理
线程可能也会有一些异常。异常发生在主线程以外的任何线程中,但这取决于abort_on_exception
。 默认情况下,此选项始终为false
。表示未处理的异常将静默地终止线程。 这可以通过将abort_on_exception = true
或$DEBUG
设置为true
来更改。
要处理异常,可以使用类的::handle_interrupt
方法。 它将使用线程异步处理异常。
线程变量和范围
在块上创建线程。 在块内创建的局部变量仅可在该块存在的线程中访问。
Ruby线程类允许通过名称创建和访问线程局部变量。 线程对象像哈希一样处理,使用[]=
写入元素,并使用[]
读取它们。
线程调度
Ruby支持通过在程序中使用::stop
和::pass
方法调度线程。
类的::stop
方法将当前正在运行的线程置于休眠状态并调度另一个线程的执行。 一旦线程处于休眠状态,实例方法唤醒被用来标记线程符合调度条件。
类的::pass
方法尝试将执行传递给另一个线程。 这取决于操作系统运行的线程是否切换。
线程优先级提供了根据优先级调度线程的操作。 高优先级线程首先安排执行。 它也取决于操作系统。 线程可以随着第一个动作增加或减少自己的优先级。
线程排除
Ruby线程排除的状态,当两个线程共享相同的数据并且其中一个线程修改该数据时,需要确保在没有线程操作数据处于不一致的状态。 例如,银行服务器。 一个线程在账户中进行汇款,其他线程正在为客户生成月度报表。
公共类方法
方法 | 描述 |
---|---|
abort_on_exception | 它返回全局“异常中止”状态,默认值为true 。 当它设置为true 时,如果在任何线程中引发异常时,则所有线程将中止。 |
abort_on_exception= | 当设置为true 时,如果引发异常,所有线程将中止。 它返回新的状态。 |
current | 它返回当前执行的线程。 |
exclusive{block} | 它将块封装在一个单独的块中,返回块的值。 |
exit | 它终止当前运行的线程并计划另一个线程运行。 |
kill(thread) | 它使指定的线程退出。 |
fork([args]*){args / block} |
它与::new 方法基本相同。 |
handle_interrupt(hash){…} | 更改异步中断时序。 |
list | 返回可运行或停止的所有线程的线程对象数组。 |
main | 返回主线程 |
new{...}/ new(*args, &proc)/ new(*args){/args/...} |
它创建一个执行给定块的新线程。 |
pass | 它给线程调度程序一个提示,以将执行传递给另一个线程。 运行的线程可能会或可能不会根据操作系统进行切换。 |
pending_interrupt?(error = nil) | 它返回异步队列是否为空? |
start([args]*){/args/block} |
它与::new 方法基本相同。 |
stop | 它停止执行当前线程,将其置于“睡眠”状态,并计划执行另一个线程。 |
公共实例方法
方法 | 描述 |
---|---|
thr[sym] | 它使用字符串或符号名称返回局部变量的值。 |
thr[sym]= | 它使用字符串或符号名称创建局部变量的值。 |
abort_on_exception | 它返回第三个“异常中止”的状态。 |
abort_on_exception= | 当设置为true 时,如果在此thr 中引发异常,所有线程将中止。 |
add_trace_func(proc) | 添加proc 作为跟踪的处理程序。 |
alive? | 如果此thr 运行或睡眠,则返回true。 |
backtrace | 它返回目标的追溯目标。 |
backtrace_locations(*args) |
它返回前面的目标的执行堆栈。 |
exit/kill/terminate | 它终止thr 并执行另一个线程运行。 |
group | 它返回包含给定线程的ThreadGroup ,或返回nil 。 |
inspect | 它将返回thr 的字符串名称,id和状态。 |
join | 调用线程将暂停执行并运行此thr 。 |
key?(sym) | 如果给定的字符串作为thr 局部变量存在,则返回true 。 |
keys | 它返回一个thr 局部变量名称的数组。 |
pending_interrupt?(error=nil) | 判断返回目标线程的异步队列是否为空。 |
priority | 它返回thr 的优先级。 |
priority= | 它将thr 的优先级设置为一个整数。 |
kill | 它与exit 方法一样。 |
raise | 它引发了给定线程的异常。 |
run | 它唤醒了thr ,使其可调度。 |
safe_level | 它返回安全级别。 |
set_trace_func(proc) | 它作为处理程序在thr 上建立proc。 |
status | 它返回thr 的状态。 |
stop? | 如果thr 休眠或终止,则返回true 。 |
terminate | 它终止thr 并计划另一个线程运行。 |
thread_variable?(key) | 如果给定的字符串作为线程局部变量存在,则返回true 。 |
thread_variable_get(key) | 它返回已设置的线程局部变量的值。 |
thread_variable_set(key, value) | 设置一个线程的局部键和值。 |
thread_variable | 它返回线程局部变量的数组。 |
value | 它等待thr 完成,使用join 并返回其值。 |
wakeup | 使给定线程有资格进行调度,尽管它仍然可能在I/O上阻塞。 |