流行的 Concurrent-Ruby 庫有一個 Concurrent::Event 類,我覺得這個類非常好。它非常整齊地封裝了 "一些執行緒需要等待另一個執行緒完成某件事情后再繼續進行 "的想法。
它只需要三行代碼就能使用:
- 一行用于創建物件 呼叫
- 當該物件準備好時,呼叫
.set。
.wait開始等待,以及
你需要用其他并發原語來創建的所有鎖和布爾運算都已經為你解決了。
參考一些檔案,以及示例用法:
老派的內核式事件,讓人想起了C 中的Win32編程。
當一個
Event被創建時,它處于unset 狀態。執行緒可以選擇#wait對該事件進行阻塞,直到被其他執行緒釋放。當一個 執行緒想提醒所有阻塞的執行緒時,它就會呼叫#set方法,然后會喚醒所有的監聽器。 然后喚醒所有的監聽器。一旦一個Event被設定,它就一直被設定。 新的執行緒呼叫#wait將立即回傳。require 'concurrent-ruby' 事件 = Concurrent::Event.new t1 = Thread.new do 放置"t1正在等待"。 事件.等待 put "事件發生了"。 結束 t2 = Thread.new Do 把"t2呼叫設定"。 事件.設定 結束 [t1, t2].each(&/span>:join)
這就列印出了如下的輸出結果
t1 is waiting
t2呼叫set。
事件發生
(因為是多執行緒,所以可能有幾種不同的順序,但是't2呼叫set'總是在'事件發生'之前出來。)
在iOS的Swift中是否有類似的東西?
uj5u.com熱心網友回復:
我認為最接近的是Swift 5.5中新的async/await語法。沒有等同于event.set的語法,但是await會等待異步的東西完成。
async let result1 = // do something asynchronous
async let result2 = //在同一時間做其他異步的事情。
// ... and keep going...
//現在讓我們收集一下結果。
return await (result1, result2)
uj5u.com熱心網友回復:
你可以使用Grand Central Dispatch DispatchSemaphore來實作你例子中的結果 - 這是一個傳統的計數信號。 每次對signal的呼叫都會使semaphore增加。 每次呼叫wait都會使semaphore遞減,如果結果小于0,就會阻塞并等待,直到semaphore為0
let semaphore = DispatchSemaphore(value: 0)
let q1 = DispatchQueue(label:"q1", target: .global(qos: .utility) )
let q2 = DispatchQueue(label:"q2", target: .global(qos: .utility) )
q1.async {
print("q1 is waiting")
semaphore.wait()
print("事件發生")
}
q2.async {
print("q2呼叫信號")
semaphore.signal()
}
輸出:
q1正在等待
q2在呼叫信號事件發生了
事件發生了
事件發生了
事件發生了
但是,如果你有多個執行緒想要等待,這個物件就不能作業了。因為每一次對wait的呼叫都會遞減semaphore,其他任務會一直被阻塞。
為此,你可以使用DispatchGroup。 你在啟動組中的任務之前呼叫enter,當任務完成后呼叫leave。 你可以使用wait來阻塞,直到該組為空,就像你的Ruby物件一樣,如果該組已經為空,wait將不會阻塞,多個執行緒可以在同一個組上wait。
let group = DispatchGroup()
let q1 = DispatchQueue(label:"q1", target: .global(qos: .utility) )
let q2 = DispatchQueue(label:"q2", target: .global(qos: .utility) )
q1.async {
print("q1 is waiting")
group.wait()
print("事件發生")
}
group.enter()
q2.async {
print("q2 calling leave")
group.leave()
}
輸出:
q1正在等待
q2呼叫離開事件發生了
如果可能的話,你通常希望在iOS上避免阻塞執行緒,因為存在死鎖的風險,而且如果你阻塞了主執行緒,你的整個應用程式將變得沒有回應。 更常見的做法是使用notify來安排代碼在組變空時執行。
我知道你的代碼只是一個臆造的例子,但是根據你實際想要做的事情和你的最低支持的 iOS 要求,可能有更好的替代方案。
- DispatchGroup
- DispatchGroup 在幾個異步任務完成時使用
notify而不是wait 來執行代碼。
- Combine 在一個管道中處理異步事件(iOS 13 ) 。
- Async/Await(iOS 15 )
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/325324.html
標籤:
