如果PUSH操作可以阻止POP操作,佇列可以無鎖定嗎?
有趣的是,「無鎖」常被錯誤地使用意思是「沒有互斥體的並發程式設計」。無鎖演算法實際上提供了進度保證,無論其他執行緒的操作如何。這意味著不應該有一個線程依賴另一個線程來繼續的程式碼。
考慮 liblfds 中的循環緩衝區佇列,其目標是在沒有明確互斥體的情況下實現並發。 PUSH 演算法涉及透過比較寫入索引並更新序號來保留槽。雖然使用單一 CAS 效率很高,但它引發了有關無鎖性的問題。
一方面,如果插槽可用,執行緒總是可以排隊。但另一方面,如果在更新序號之前中斷 PUSH 操作,則後續的 POP 操作將失敗,使佇列顯示為空。
根據無鎖性的定義,「一個結構是可用的,如果任何執行緒都會無限期地掛起,」這個隊列並不是嚴格無鎖的。它具有隱藏的互斥機制(寫入索引和序號),由於關鍵區域中的寫入器掛起,寫入器可能無法插入元素。
但是,隊列仍然可能表現出一些有用的屬性。由於其低開銷,它具有合理的無競爭性能,合理地處理競爭性能,並且部分地不受上下文切換影響。此外,它支援來自中斷或訊號的佇列訪問,儘管它在處理非同步執行緒終止方面有限制。
雖然 liblfds 佇列可能不完全滿足無鎖的嚴格定義,但它對於某些情況仍然可能是有益的應用程式。它提供了部分進度保證和良好的性能特徵,而沒有基於互斥鎖的解決方案的複雜性。
以上是如果 PUSH 操作可以阻止 POP 操作,那麼循環緩衝區佇列是否真正無鎖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!