红宝石 |多线程简介
多线程是 Ruby 最有用的属性,它允许对程序的两个或多个部分进行并发编程,以最大限度地利用 CPU。程序的每个部分都称为Thread 。因此,换句话说,线程是进程中的轻量级进程。一个普通的程序包含一个线程,所有的语句或指令都是按顺序执行的。但是多线程程序包含多个线程,并且在每个线程内语句或指令顺序执行,但线程本身在多核处理器上并发执行。与单线程相比,多线程通过执行多个任务减少了内存使用量。在Ruby 1.9之前,线程在解释器中切换,称为绿色线程。但从Ruby 1.9 开始,线程由操作系统执行。在同一个 Ruby 应用程序中运行的两个线程永远不可能真正并发。在 Ruby 中,多线程程序是在Thread 类的帮助下创建的,并通过调用一个块来创建一个新线程,即Thread.new 。
在 Ruby 中创建线程
在 Ruby 中,创建一个新线程非常容易。您可以通过三个块( Thread.new 、 Thread.start或Thread.fork )在程序中创建线程。通常使用Thread.new来创建线程。一旦创建线程,原始线程将从这些线程创建块之一返回并使用下一条语句继续执行。
句法:
# Original thread is running
# creating thread
Thread.new
{
# new thread runs here
}
# Outside the block
# Original thread is running
例子:
# Ruby program to illustrate
# creation of threads
#!/usr/bin/ruby
# first method
def Geeks1
a = 0
while a <= 3
puts "Geeks1: #{a}"
# to pause the execution of the current
# thread for the specified time
sleep(1)
# incrementing the value of a
a = a + 1
end
end
# Second method
def Geeks2
b = 0
while b <= 3
puts "Geeks2: #{b}"
# to pause the execution of the current
# thread for the specified time
sleep(0.5)
# incrementing the value of a
b = b + 1
end
end
# creating thread for first method
x = Thread.new{Geeks1()}
# creating thread for second method
y= Thread.new{Geeks2()}
# using Thread.join method to
# wait for the first thread
# to finish
x.join
# using Thread.join method to
# wait for the second thread
# to finish
y.join
puts "Process End"
输出:
Geeks1: 0
Geeks2: 0
Geeks2: 1
Geeks1: 1
Geeks2: 2
Geeks2: 3
Geeks1: 2
Geeks1: 3
Process End
注意:输出可能会有所不同,因为线程的资源是由操作系统分配的。
终止线程
当一个 Ruby 程序终止时,与该程序相关的所有线程也会被终止。用户可以使用class ::kill杀死线程。
句法:
Thread.kill(thread)
线程变量及其作用域
由于线程是由块定义的,因此它们可以访问在块范围内定义的局部、全局和实例变量。存在于线程块中的变量是该线程的局部变量,它们不会被任何其他线程块访问。 Thread 类允许通过名称创建和访问线程局部变量。如果两个或多个线程要同时读取和写入同一个变量,则必须有线程同步。
例子:
# Ruby program to illustrate
# Thread variables
#!/usr/bin/ruby
# Global variable
$str = "GeeksforGeeks"
# first method
def Geeks1
# only access by Geeks1 Thread
a = 0
while a <= 3
puts "Geeks1: #{a}"
# to pause the execution of the current
# thread for the specified time
sleep(1)
# incrementing the value of a
a = a + 1
end
# accessing str
puts "Global variable: #$str"
end
# Second method
def Geeks2
# only access by Geeks2 Thread
b = 0
while b <= 3
puts "Geeks2: #{b}"
# to pause the execution of the current
# thread for the specified time
sleep(0.5)
# incrementing the value of a
b = b + 1
end
# accessing str
puts "Global variable: #$str"
end
# creating thread for first method
x = Thread.new{Geeks1()}
# creating thread for second method
y= Thread.new{Geeks2()}
# using Thread.join method to
# wait for the first thread
# to finish
x.join
# using Thread.join method to
# wait for the second thread
# to finish
y.join
puts "Process End"
输出:
Geeks1: 0
Geeks2: 0
Geeks2: 1
Geeks1: 1
Geeks2: 2
Geeks2: 3
Geeks1: 2
Global variable: GeeksforGeeks
Geeks1: 3
Global variable: GeeksforGeeks
Process End