## 21.多線程
通常,程序是逐行讀取的,并由計算機逐步執行。 在任何給定的時間點,計算機僅執行一條指令 1。 隨著技術的進步,可以同時執行許多指令,這種同時執行許多操作的過程稱為多處理或并行處理。 想象一下,你要吃 5 個披薩。 你需要花費很長時間。 如果你也可以帶來你的朋友,那么你的人們可以分擔負擔。 如果你可以組成一個由 20 個人組成的小組,那么吃 5 個披薩就變得像吃零食一樣容易。 完成分配任務所需的時間大大減少。
在 Ruby 編程中,你可以使解釋器以并行方式執行代碼。 并行執行代碼的過程稱為多線程。 要顯示多線程的工作方式,請在文本編輯器中鍵入以下程序并執行。
```rb
#!/usr/bin/ruby
# multithreading.rb
a = Thread.new{
i = 1
while i<=10
sleep(1)
puts i
i += 1
end
}
puts "This code comes after thread"
a.join
```
這是程序輸出
```rb
This code comes after thread
1
2
3
4
5
6
7
8
9
10
```
與其他程序不同,此程序將花費 10 秒鐘執行。 看一下程序和輸出。 `puts "This code comes after thread"`之后
```rb
a = Thread.new{
i = 1;
while i<=10
sleep(1)
puts i
i += 1
end
}
```
但是它首先被打印。 在上面顯示的語句中,我們創建一個名為 a 的新線程,在該線程中,我們使用`while`循環從 1 到 10 進行打印。請注意,我們調用了一個名為`sleep(1)`的函數,該函數可使進程休眠或保持空閑一秒鐘。 創建了一個線程,當線程運行時,Ruby 解釋器檢查主線程,并且遇到`puts "This code comes after thread"`,因此它在執行我們創建的新線程 a 的同時打印出字符串并并行執行,因此 1 到 10 在插入`sleep(1)`時被打印,每個循環執行大約需要 1 秒鐘。 因此,在 10 秒鐘后,線程 a 完成。
`a.join`告訴 Ruby 解釋器等待線程完成執行。 一旦執行了`a.join`(如果有)之后的語句,線程 a 的執行結束。 由于之后沒有語句,程序終止。
這是另一個清楚說明多線程的程序。 仔細檢查該程序,嘗試了解它的工作原理,稍后我將對其進行解釋
```rb
#!/usr/bin/ruby
# multithreading_1.rb
def func1
i=0
while i<=2
puts "func1 at: #{Time.now}"
sleep(2)
i=i+1
end
end
def func2
j=0
while j<=2
puts "func2 at: #{Time.now}"
sleep(1)
j=j+1
end
end
puts "Started At #{Time.now}"
t1 = Thread.new{func1()}
t2 = Thread.new{func2()}
t1.join
t2.join
puts "End at #{Time.now}"
```
看一下突出顯示的代碼,我們創建了兩個線程`t1`和`t2`。 在線程`t1`中,我們稱為方法`func1()`,在線程`t2`中,我們稱為方法`func2()`,這樣做是同時執行`func1()`和`func2()`。 執行后,輸出結果將如下所示: <sup class="footnote">[ [51](#_footnotedef_51 "View footnote.") ]</sup>
```rb
Started At Sun Apr 25 09:37:51 +0530 2010
func1 at: Sun Apr 25 09:37:51 +0530 2010
func2 at: Sun Apr 25 09:37:51 +0530 2010
func2 at: Sun Apr 25 09:37:52 +0530 2010
func1 at: Sun Apr 25 09:37:53 +0530 2010
func2 at: Sun Apr 25 09:37:53 +0530 2010
func1 at: Sun Apr 25 09:37:55 +0530 2010
End at Sun Apr 25 09:37:57 +0530 2010
```
從輸出中可以看到,`func1`和`func2`打印的輸出是隔行掃描的,這證明它們是并行執行的。 請注意,在`func1`中,通過提供`sleep(2)`使線程休眠 2 秒,在`func2`中,通過提供`sleep(1)`使線程休眠 1 秒。
我對 [multithreading_1.rb](code/multithreading_1.rb) 進行了一些小的更改,以產生 [multithreading_2.rb](code/multithreading_2.rb) ,該結果幾乎與 [multithreading_1.rb](code/multithreading_1.rb) 的結果相同,因此這里是其代碼:
```rb
#!/usr/bin/ruby
# multithreading_2.rb
def func name, delay
i=0
while i<=2
puts "#{name} #{Time.now}"
sleep delay
i=i+1
end
end
puts "Started At #{Time.now}"
t1 = Thread.new{func "Thread 1:", 2}
t2 = Thread.new{func "Thread 2:", 3}
t1.join
t2.join
puts "End at #{Time.now}"
```
我沒有使用兩個函數`func1`和`func2`,而是編寫了一個名為`func`的函數,該函數接受名稱和時間延遲作為輸入。 其中的循環會打印出傳遞的名稱和執行該語句的時間。 注意這些聲明
```rb
t1 = Thread.new{func "Thread 1:", 2}
t2 = Thread.new{func "Thread 2:", 3}
```
我們創建兩個線程`t1`和`t2`。 在線程`t1`中,我們調用函數`func`并傳遞名稱`Thread 1:`并告訴它休眠 2 秒鐘。 在線程`t2`中,我們調用相同的`func`,并傳遞與`Thread 2:`相同的名稱,并在每次循環迭代中告訴它休眠 3 秒。 并在執行程序時產生以下輸出
```rb
Started At Sun Apr 25 09:44:36 +0530 2010
Thread 1: Sun Apr 25 09:44:36 +0530 2010
Thread 2: Sun Apr 25 09:44:36 +0530 2010
Thread 1: Sun Apr 25 09:44:38 +0530 2010
Thread 2: Sun Apr 25 09:44:39 +0530 2010
Thread 1: Sun Apr 25 09:44:40 +0530 2010
Thread 2: Sun Apr 25 09:44:42 +0530 2010
End at Sun Apr 25 09:44:45 +0530 2010
```
這與 [multithreading_1.rb](code/multithreading_1.rb) 產生的輸出非常相似。
### 21.1。 線程變量的范圍
線程可以訪問主進程中的變量,以以下程序( [thread_variables.rb](code/thread_variables.rb) )為例
```rb
#!/usr/bin/ruby
# thread_variables.rb
variable = 0
puts "Before thread variable = #{variable}"
a = Thread.new{
variable = 5
}
a.join
puts "After thread variable = #{variable}"
```
輸出量
```rb
Before thread variable = 0
After thread variable = 5
```
輸入程序并運行。 它將產生上面顯示的結果。 從程序中可以看到,在創建線程之前,我們將名為`variable`的變量初始化為 0。 在線程內部,我們將`variable`的值更改為 5。在線程塊之后,我們輸出的變量值現在為 5。該程序向我們展示了你可以訪問和操作在主線程中聲明的變量。
現在讓我們看看是否可以在線程范圍之外訪問在線程內部創建的變量? 鍵入以下程序( [thread_variables_1.rb](code/thread_variables_1.rb) )并執行
```rb
#!/usr/bin/ruby
# thread_variables_1.rb
variable = 0
puts "Before thread variable = #{variable}"
a = Thread.new{
variable = 5
thread_variable = 72
puts "Inside thread thread_variable = #{thread_variable}"
}
a.join
puts "=================\nAfter thread\nvariable = #{variable}"
puts "thread_variable = #{thread_variable}"
```
Output
```rb
Before thread variable = 0
Inside thread thread_variable = 72
=================
After thread
variable = 5
thread_variables_1.rb:13: undefined local variable or method `thread_variable' for main:Object (NameError)
```
在上面的程序中,我們看到我們在線程`a`中創建了一個名為 thread_variable 的變量,現在我們嘗試在以下行中對其進行訪問:
```rb
puts "thread_variable = #{thread_variable}"
```
如你所見,該程序/ Ruby 解釋器吐出錯誤的輸出如下所示:
```rb
thread_variables_1.rb:13: undefined local variable or method `thread_variable' for main:Object (NameError)
```
它說有一個名為`thread_variable`的未定義局部變量或方法。 這意味著主線程中的語句無法訪問線程`a`中聲明的變量。 因此,從前兩個示例可以清楚地看出,線程可以訪問主線程中聲明的變量,而線程的作用域中聲明的變量不能被主作用域中的語句訪問。
### 21.2。 線程排除
假設有兩個共享同一資源的線程,則將該資源作為變量。 假設第一個線程修改了變量,而第二個線程嘗試訪問變量時,會發生什么呢? 答案很簡單明了,盡管程序運行似乎沒有錯誤,但你可能無法獲得理想的結果。 這個概念很難理解,讓我嘗試用一??個例子來解釋它。 輸入并執行 [thread_exclusion.rb](code/thread_exclusion.rb)
```rb
#!/usr/bin/ruby
# thread_exclusion.rb
x = y = 0
diff = 0
Thread.new {
loop do
x+=1
y+=1
end
}
Thread.new {
loop do
diff += (x-y).abs
end
}
sleep(1) # Here main thread is put to sleep
puts "difference = #{diff}"
```
Output
```rb
difference = 127524
```
仔細閱讀程序。 在開始任何線程之前,我們將三個變量`x`,`y`和 diff 分配給值 0。然后在第一個線程中,我們開始一個循環,在該循環中我們增加`x`和`y`的值。 在另一個線程中,我們找到`x`和`y`之間的區別,并將其保存在名為`diff`的變量中。 在第一個線程中`x`和`y`同時增加,因此語句`diff += (x-y).abs`不應對變量`diff`添加任何內容,因為`x`和`y`始終相等,并且它們的差值始終為零,因此 它們的差的絕對值也將始終為零。
在此程序中,我們不等待線程加入(因為它們包含無限循環),我們使用命令`sleep(1)`使主循環休眠一秒鐘,然后在以下語句中打印 diff 的值
```rb
puts "difference = #{diff}"
```
人們會期望該值為零,但我們得到的值為 127524,在你的計算機中,該值可能會有所不同,因為它取決于機器速度,運行的處理器和其他參數。 但是道德是`diff`應該為零有一定價值,為什么呢?
我們在第一個循環中看到`x`遞增,然后`y`遞增,假設`x`的值為 5,y 值為 4,即`x`剛在語句中遞增 `x += 1`,現在 Ruby 解釋器將要讀取并執行`y += 1`,這將使`y`從 4 變為 5。在此階段,第二個線程由計算機執行。 所以在聲明中
```rb
diff += (x-y).abs
```
將`x`設置為 5,將`y`設置為 4 將意味著`diff`將遞增 1。以類似的方式,當主循環休眠一秒鐘時,我們創建的兩個線程將完成數千個循環周期, 因此`diff`的值將顯著增加。 這就是為什么我們將 diff 的值當作一個大數字來獲取的原因。
好了,我們已經看到了如何不以錯誤的方式編寫程序,現在讓我們看看如何以正確的方式編寫程序。 現在,我們的任務是同步已創建的兩個線程,以便當另一個線程處于某個繁忙進程的中間時,一個線程不會訪問其他線程資源。 為此,我們將使用互斥體,即互斥。 在文本編輯器中鍵入以下程序 [thread_exclusion_1.rb](code/thread_exclusion_1.rb) 并執行它
```rb
#!/usr/bin/ruby
# thread_exclusion_1.rb
require 'thread'
mutex = Mutex.new
x = y = 0
diff = 0
Thread.new {
loop do
mutex.synchronize do
x+=1
y+=1
end
end
}
Thread.new {
loop do
mutex.synchronize do
diff += (x-y).abs
end
end
}
sleep(1) # Here main thread is put to sleep
puts "difference = #{diff}"
```
Output
```rb
difference = 0
```
如上所示,我們將輸出顯示為`difference = 0`,這意味著`diff`變量為零。 某些原因阻止了第二個線程在第一個線程繁忙時訪問第一個線程中的`x`和`y`。 這兩個線程如何學會正確地共享資源。 仔細研究代碼,我們看到我們通過鍵入包含了一個線程包
```rb
require 'thread'
```
接下來,我們使用以下命令創建了一個名為 Mutex 的 Mutex 變量。
```rb
mutex = Mutex.new
```
那么代碼就和往常一樣,除了線程內部。 讓我們看一下第一個線程
```rb
Thread.new {
loop do
mutex.synchronize do
x += 1
y += 1
end
end
}
```
我們看到`x += 1`和`y += 1`語句包含在`mutex.synchronize`塊中。 同樣,計算`x`和`y`之差的代碼也包含在`mutex.synchronize`塊中,如下所示:
```rb
Thread.new {
loop do
mutex.synchronize do
diff += (x-y).abs
end
end
}
```
通過這樣做,我們告訴計算機這兩個線程共享一個公共資源,并且只有另一個線程釋放該資源時,一個線程才能訪問該資源。 這樣,當在`diff += (x-y).abs`中計算出差(`diff`)時,`x`和`y`的值將始終相等,因此 diff 永遠不會增加并且永遠保持為零。
### 21.3。 死鎖
你是否曾經站在隊列中,或等待過什么。 我們都在機場等了一個地方,以便對我們的行李進行掃描和清理。 可以說行李掃描機出故障了,你被困在機場。 預計你將參加重要的公司會議,并且有重要的演講,并且你必須發表重要的講話。 由于行李掃描儀發生故障,因此你所需要的資源不可用,并且你掌握了在會議中進行交談的關鍵知識,因此會議忙得不可開交。 會議中的一個可能會答應帶他的家人去看電影,他可能會在延遲的會議之后回來很晚,因此一切都搞砸了。
想象一下,行李掃描儀,你,一個必須聽見你的會議的人,是 Ruby 程序的線程。 由于行李掃描儀不會釋放資源(你的行李),因此你的流程將被延遲,并且由于延遲,許多其他依賴于你的流程也會延遲。 這種情況稱為死鎖。 它也發生在 Ruby 程序中。 每當出現這種情況時,人們就會等待而不是向前沖。 你等待行李被放行,公司等待你的到來,芒家族等待他將其帶到電影中。 如果不等人們趕時間,就會造成混亂。 Ruby 具有避免這種混亂并處理這種死鎖的機制。 我們使用一種稱為條件變量的東西。 看下面的程序( [thread_condition_variable.rb](code/thread_condition_variable.rb) ),鍵入并執行它。
```rb
#!/usr/bin/ruby
# thread_condition_variable.rb
require 'thread'
mutex = Mutex.new
c = ConditionVariable.new
a = Thread.new {
mutex.synchronize {
puts "Thread a now waits for signal from thread b"
c.wait(mutex)
puts "a now has the power to use the resource"
}
}
puts "(Now in thread b....)"
b = Thread.new {
mutex.synchronize {
puts "Thread b is using a resource needed by a, once its done it will signal to a"
sleep(4)
c.signal
puts "b Signaled to a to acquire resource"
}
}
a.join
b.join
```
Output
```rb
Thread a now waits for signal from thread b
(Now in thread b....)
Thread b is using a resource needed by a, once its done it will signal to a
b Signaled to a to acquire resource
a now has the power to use the resource
```
仔細研究程序并輸出。 查看輸出。 首先,執行線程`a`中的語句,并打印出線程`a`正在等待線程`b`發出信號以繼續執行該語句。 參見線程`a`,我們編寫了代碼`c.wait(mutex)`,其中`c`是代碼中聲明的條件變量,如下所示:
```rb
c = ConditionVariable.new
```
所以現在線程 a 等待,現在在線程`b 中遇到以下行時,執行集中在線程 b 上
```rb
puts "Thread b is using a resource needed by a, once its done it will signal to a"
```
它打印出線程`b`正在使用`a`所需的某些資源,下一個線程`b`休眠 4 秒,因為我們在其中指定了`sleep(4)`。 可以避免使用`sleep`語句,我給出了`sleep`,因為在讀者執行程序時,它使他等待并感到條件變量的工作原理。
然后,在 4 秒鐘后,線程`b`向線程`a`發出信號,其等待可以使用語句`c.signal`結束。 現在,線程 a 接收信號并可以執行其其余語句,即在`c.signal`之后,線程`a`和線程`b`可以同時執行。
### 21.4。 創建多個線程
假設你有一種情況,必須創建許多線程,并且必須以優雅的方式完成,說一種情況可能會出現,你甚至不知道可以創建多少個線程,但是必須創建它們并且 程序應該等待他們加入然后退出,所以讓我們看看如何編寫代碼。
因此,在你的文本編輯器中鍵入以下程序并運行它
```rb
# many_threads.rb
def launch_thread string
thread = Thread.new do
3.times do
puts string
sleep rand(3)
end
end
return thread
end
threads = []
threads << launch_thread("Hi")
threads << launch_thread("Hello")
threads.each {|t| t.join}
```
Output
```rb
Hi
Hello
Hello
Hello
Hi
Hi
```
如果你沒有獲得如上所述的確切輸出,請不要擔心,因為程序中存在一些隨機性。 讓我解釋一下該程序,以便你看清楚它。
首先,我們聲明一個將容納線程的數組,如下所示
```rb
threads = []
```
接下來,我們將使用函數`launch_thread`將值放入線程數組,如下所示
```rb
threads << launch_thread("Hi")
```
讓我們分析`launch_thread`函數中發生的事情,首先我們有一個如下所示的函數
```rb
def launch_thread string
…....
end
```
我們從函數返回一個名為`thread`的變量
```rb
def launch_thread string
return thread
end
```
我們將新創建的線程分配給變量線程
```rb
def launch_thread string
thread = Thread.new do
end
return thread
end
```
我們在新創建的線程中放入一些代碼
```rb
def launch_thread string
thread = Thread.new do
3.times do
puts string
sleep rand(3)
end
end
return thread
end
```
而已。 簡而言之,我們創建線程,在其中運行代碼,然后將其返回并存儲在`threads`數組中。 這行也發生了同樣的事情
```rb
threads << launch_thread("Hello")
```
現在,我們必須等待每個線程加入主程序(或主線程)。 因此,我們編寫了如下所示的連接代碼
```rb
threads.each {|t| t.join}
```
這將等待所有線程完成并與主代碼聯接。
因此,我們編寫了一個程序,該程序可以創建所需的任意數量的線程(在上面的示例中為兩個),所有線程將被收集到一個數組中,主程序將等待所有線程完成并與之連接,然后 將退出。
現在看看 [many_threads_1.rb](code/many_threads_1.rb) 和 [many_threads_2.rb](code/many_threads_2.rb) ,執行它們并向自己解釋它們如何工作。 最好為他們寫一個好的解釋并郵寄給我,以便我可以將其放在這本書中。
```rb
# many_threads_1.rb
def launch_thread string
thread = Thread.new do
3.times do
puts string
sleep rand(3)
end
end
return thread
end
threads = []
4.times do |i|
threads << launch_thread("Thread #{i}")
end
threads.each {|t| t.join}
```
```rb
# many_threads_2.rb
def launch_thread string
thread = Thread.new do
3.times do
puts string
sleep rand(3)
end
end
return thread
end
threads = []
puts "How many threads should run?"
count = gets.to_i
count.times do |i|
threads << launch_thread("Thread #{i}")
end
threads.each {|t| t.join}
```
### 21.5。 線程異常
每當程序運行時發生異常,并且如果異常處理不當,程序就會終止。 讓我們看看線程中有異常時會發生什么。 在文本編輯器中鍵入代碼 [thread_exception_true.rb](code/thread_exception_true.rb) 并執行它。
```rb
#!/usr/bin/ruby
# thread_exception_true.rb
t = Thread.new do
i = 5
while i >= -1
sleep(1)
puts 25 / i
i -= 1
end
end
t.abort_on_exception = true
sleep(10)
puts "Program completed"
```
Output
```rb
5
6
8
12
25
thread_exception_true.rb:8:in `/': divided by 0 (ZeroDivisionError)
from thread_exception_true.rb:8
from thread_exception_true.rb:4:in `initialize'
from thread_exception_true.rb:4:in `new'
from thread_exception_true.rb:4
```
注意,在程序中我們創建了一個名為`t`的線程,如果你很安靜,則程序中沒有`t.join`。 與其等待線程加入,不如等待足夠長的時間來完成線程。 為了使線程完成,我們使用語句`sleep(10)`等待 10 秒。
注意我們設置的`t.abort_on_exception = true`行,如果線程`t`中引發異常,則程序必須中止。 現在讓我們分析線程`t`中的內容。 線程`t`包含以下代碼
```rb
t = Thread.new do
i = 5
while i >= -1
sleep(1)
puts 25 / i
i -= 1
end
end
```
注意,我們將 25 除以`i`,然后得出除法結果。 `i`在每次循環迭代中遞減 1,因此,當`i`變為零且被其除以 25 時,它將引發異常。 因此,在循環的第六次迭代中,將 25 除以零,引發異常,并通過吐出以下內容停止程序
```rb
thread_exception_true.rb:8:in `/': divided by 0 (ZeroDivisionError)
from thread_exception_true.rb:8
from thread_exception_true.rb:4:in `initialize'
from thread_exception_true.rb:4:in `new'
from thread_exception_true.rb:4
```
發生這種情況是因為我們已將`t.abort_on_exception`設置為`true`(請參見突出顯示的代碼)。 如果將其設置為`false`會發生什么。 看一下程序 [thread_exception_false.rb](code/thread_exception_false.rb) 。 在程序中,我們將`t.abort_on_exception`設置為`false`。 在文本編輯器中鍵入程序并運行
```rb
#!/usr/bin/ruby
# thread_exception_false.rb
t = Thread.new do
i = 5
while i >= -1
sleep(1)
puts 25 / i
i -= 1
end
end
t.abort_on_exception = false
sleep(10)
puts "Program completed"
```
看一下輸出
```rb
5
6
8
12
25
Program completed
```
從輸出中可以看到,沒有異常發生的痕跡 4。 執行線程`t`之后的代碼,我們得到顯示為`Program Completed`的輸出。 這是因為我們將`abort_on_exception`設置為`false`。
你可以從最后兩個程序中看到我們尚未使用`t.join`,相反,我們已經等待了足夠長的時間以終止線程。 之所以這樣,是因為一旦我們將線程(導致)與父線程(在這種情況下為主線程)連接在一起,子線程中出現的異常就會傳播到父線程/等待線程,因此`abort_on_exception`甚至沒有作用 設置為 false。 因此,每當異常發生時,它就會反映在我們的終端上。
### 21.6。 線程類方法
你可以使用某些線程方法來操縱線程的屬性。 這些在下面列出。 如果你一點都不懂,那就不用擔心。
<colgroup><col style="width: 33.3333%;"> <col style="width: 33.3333%;"> <col style="width: 33.3334%;"></colgroup>
| 斯諾 | 方法 | 它能做什么 |
| --- | --- | --- |
| 1。 | Thread.abort_on_exception | 返回異常情況下全局中止的狀態。 默認值為 false。 設置為 true 時,如果任何線程中引發異常,將導致所有線程中止(進程將退出(0))。 |
| 2。 | Thread.abort_on_exception = | 設置為 true 時,如果引發異常,則所有線程將中止。 返回新狀態。 |
| 3。 | 線程臨界 | 返回全局線程嚴重條件的狀態。 |
| 4。 | Thread.critical = | 設置全局線程緊急條件的狀態并返回。 設置為 true 時,禁止調度任何現有線程。 不會阻止新線程的創建和運行。 某些線程操作(例如停止或殺死線程,在當前線程中休眠以及引發異常)可能導致即使在關鍵部分中也要調度線程。 |
| 5, | 線程電流 | 返回當前正在執行的線程。 |
| 6。 | 線程退出 | 終止當前正在運行的線程并安排另一個線程運行。 如果此線程已被標記為已終止,則 exit 返回該線程。 如果這是主線程或最后一個線程,請退出進程。 |
| 7 | Thread.fork {塊} | Thread.new 的同義詞 |
| 8。 | Thread.kill(aThread) | 使給定的 aThread 退出 |
| 9。 | 線程列表 | 返回所有可運行或已停止線程的 Thread 對象數組。 線。 |
| 10。 | 線程主 | 返回該進程的主線程。 |
| 11。 | Thread.new([arg] *){| args | 阻止 | 創建一個新線程以執行塊中給出的指令,然后開始運行它。 傳遞給 Thread.new 的所有參數都傳遞給該塊。 |
| 12 | 線程傳遞 | 調用線程調度程序以將執行傳遞給另一個線程。 |
| 13 | Thread.start([args] *){| args | 阻止 | 基本上與 Thread.new 相同。 但是,如果 Thread 類是子類,則在該子類中調用 start 不會調用該子類的 initialize 方法。 |
| 14。 | 線程停止 | 停止當前線程的執行,使其進入睡眠狀態,并計劃另一個線程的執行。 將關鍵條件重置為 false |
### 21.7。 線程實例方法
由于 Ruby 中的所有內容都是對象,因此 ia 線程也是對象。 與許多對象一樣,線程具有可以調用以訪問或設置線程中的屬性的函數或方法。 下面列出了一些功能及其用途(thr 是 Thread 類的實例變量):
<colgroup><col style="width: 33.3333%;"> <col style="width: 33.3333%;"> <col style="width: 33.3334%;"></colgroup>
| Sno. | Method | What it does |
| --- | --- | --- |
| 1 個 | 活著嗎? | 如果線程處于活動狀態或睡眠狀態,則此方法返回 true。 如果線程已終止,則返回 false。 |
| 2 | 退出 | 殺死或退出線程 |
| 3 | thr.join | 該進程等待線程與創建子線程的進程或線程聯接。 子線程完成執行后,主線程在 thr.join 之后執行語句 |
| 4 | 殺傷力 | 相同的廣告退出次數 |
| 5 | 優先級 | 獲取線程的優先級。 |
| 6 | thr.priority = | 設置線程的優先級。 優先級越高,具有較高編號的線程將具有更高的優先級。 |
| 7 | thr.raise(anException) | 從 thr 引發異常。 呼叫者不必是 thr。 |
| 8 | 運行 | 喚醒 thr,使其有資格進行調度。 如果不在關鍵部分,則調用調度程序。 |
| 10 | 喚醒 | 將 thr 標記為可進行調度,但是它仍可能在 I / O 上處于阻塞狀態。 |
| 11 | 狀態 | 返回 thr 的狀態:如果 thr 正在睡眠或正在等待 I / O,則進入 sleep;如果 thr 正在執行,則運行;如果 thr 正常終止,則返回 false;如果 thr 終止,則返回 nil。 |
| 12 | 停止嗎? | 等待 thr 通過 Thread.join 完成并返回其值。 |
| 13 | thr [aSymbol] | 屬性參考-使用符號或 aSymbol 名稱返回線程局部變量的值。 如果指定的變量不存在,則返回 nil。 |
| 14 | thr [aSymbol] = | 屬性分配-使用符號或字符串設置或創建線程局部變量的值。 |
| 15 | thr.abort_on_exception | 返回 thr 的異常情況中止的狀態。 默認值為 false。 |
| 16 | thr.abort_on_exception = | 設置為 true 時,如果 thr 中引發異常,將導致所有線程(包括主程序)中止。 該過程將有效退出(0)。 |
- 前言
- 紅寶石
- 先決條件
- 1.安裝 Ruby
- 2.在線資源
- 3.入門
- 4.比較與邏輯
- 5.循環
- 6.數組
- 7.哈希和符號
- 8.范圍
- 9.功能
- 10.可變范圍
- 11.類&對象
- 12.安全導航
- 13.打破大型程序
- 14.結構和 OpenStruct
- 15. Rdoc
- 16. Ruby 樣式指南
- 17.模塊和混入
- 18.日期和時間
- 19.文件
- 20. Proc,Lambda 和塊
- 21.多線程
- 22.異常處理
- 23.正則表達式
- 24.寶石
- 25.元編程
- 26.基準
- 27.測試驅動開發
- 28.觀察者模式
- 29.模板模式
- 30.工廠模式
- 31.裝飾圖案
- 32.適配器模式
- 33.單例模式
- 34.復合模式
- 35.建造者模式
- 36.策略模式
- 贊助商
- 捐
- 人們怎么說
- 版權
- 取得這本書