我有一個作業,其中有 2 個數字(a 和 b)和一個計數(n)。我需要首先生成亂數,這將是每個執行緒休眠的時間。然后,每個執行緒計算 a 和 b 的和、差、乘積和除法(分別)并重復 n 次。例如:
a = 10
b = 2
n = 2
SUM: 12
DIFFERENCE: 8
PRODUCT: 20
DIVISION: 5
SUM: 12
DIFFERENCE: 8
PRODUCT: 20
DIVISION: 5
在每行之間,程式會休眠幾秒鐘。順序必須是和、差、乘積和除法。我不能重復使用佇列或殺死/生成執行緒。我的第一個想法是使用 4 個條件變數來規定執行緒需要運行的順序。我想出了這個:
mutex = Mutex.new
resources = Array.new(4) { ConditionVariable.new }
t1 = Thread.new do
mutex.synchronize do
puts "Thread 1"
sleep(3)
resources[0].signal
end
end
t2 = Thread.new do
mutex.synchronize do
resources[0].wait(mutex)
puts "Thread 2"
sleep(3)
resources[1].signal
end
end
t3 = Thread.new do
mutex.synchronize do
resources[1].wait(mutex)
puts "Thread 3"
sleep(3)
resources[2].signal
end
end
t4 = Thread.new do
mutex.synchronize do
resources[2].wait(mutex)
puts "Thread 4"
sleep(3)
end
end
t1.join
t2.join
t3.join
t4.join
但我收到了這個死鎖錯誤: main.rb:39:in 'join': No live threads left. Deadlock? (fatal)
這種方法可行嗎?我應該怎么做才能修復它?還有其他更好的方法可以奏效嗎?
uj5u.com熱心網友回復:
我不是 ruby?? 專家,但在我使用過的所有其他語言中,“條件變數”這個名稱用詞不當。對于稱為“變數”的任何其他事物,我們希望如果一個執行緒更改它,另一個執行緒可以稍后出現并查看它已更改。這不是條件變數的作業方式。
當執行緒 A “通知/發出信號”一個條件變數時,它會“喚醒”已經在等待的其他執行緒,但如果此時沒有其他執行緒發生等待,則信號/通知完全沒有任何作用。
條件變數不記得通知。
這是我認為可能發生的事情:
該t1執行緒鎖定互斥鎖,然后睡覺。
其他三個執行緒都啟動了,并且在等待互斥鎖時都被阻塞了。
該t1螺紋從回傳sleep(3),并將其用信號通知條件變數。但是,條件變數不會記住通知。其他執行緒都無法wait(mutex)接聽他們的電話,因為他們都仍在試圖通過mutex.synchronize。通知丟失。
該t1執行緒葉synchronized塊,其他執行緒獲得在他們的synchronized塊,一個接一個,直到所有的人都在等待信號。
同時,主執行緒一直掛在t1.join(). 該呼叫在t1執行緒結束時回傳,但隨后主執行緒呼叫t2.join() t2正在等待信號、t3正在等待信號、t4正在等待信號,并且主執行緒正在等待t2死亡。
沒有更多的實時執行緒。
同樣,不是 ruby?? 專家,但在所有其他語言中,使用條件變數等待某些“條件”的執行緒必須執行以下操作:
# The mutex prevents other threads from modifying the "condition"
# (i.e., prevents them from modifying the `sharedData`.)
mutex.lock()
while ( sharedData.doesNotSatisfyTheCondition() ) {
# The `wait()` call _temporarily_ unlocks the mutex so that other
# threads may make the condition become true, but it's _guaranteed_
# to re-lock the mutex before it returns.
conditionVar.wait(mutex)
}
# At this point, the condition is _guaranteed_ to be true.
sharedData.doSomethingThatRequiresTheConditionToBeTrue()
mutex.unlock()
這里發生的最重要的事情是,主叫方不等待,如果條件已經是真實的。如果條件已經為真,則通知可能已經發生。我們錯過了它,如果我們現在等待它,我們可能會永遠等待。
另一件重要的事情是,在我們等待并收到通知后,我們再次檢查條件。取決于編程語言的規則、作業系統和程式的體系結構;它可能是可能wait()過早回傳。
使條件變為真很簡單:
mutex.lock()
sharedData.doSomethingThatMakesTheConditionTrue()
conditionVar.notify()
mutex.unlock()
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/358259.html
上一篇:Ruby的哈希“值”之間有區別嗎?和“has_value?”
下一篇:在Ruby中從.map中排除資料
