lock-free和lock的一些本質區別

編編成程 發佈 2023-01-25T23:25:19.439055+00:00

lock的本質就是你得到鎖,完成你的工作,然後你知道在這種狀態下沒有人可以打擾你,最後你釋放了鎖。相關lock-free的一些思考有:很多lock-free的算法最終都要落地到原子級別的提交,比如pointer, 通過compare and swap。

lock的本質就是你得到鎖,完成你的工作,然後你知道在這種狀態下沒有人可以打擾你,最後你釋放了鎖


lock-free的本質是你在其他地方安心的做你的事情,當你做完之後,你原子級別的提交這段共走量到可見區,如果失敗你會不斷的重複去嘗試。實現的本質是基於處理器的CAS(事務內存 std::atomic<T>::compare_exchange_weak())或者是atomic increment(事務內存). data type還能擁有對應的lock-free屬性,所謂lock-free屬性也能被叫為stateless, 這個屬性暗示著對應的object不會存在中間狀態,如果他被中斷或者被其他線程在中間狀態進行讀取,都是保證安全的


相關lock-free的一些思考有:

  • 很多lock-free的算法最終都要落地到原子級別的提交,比如pointer, 通過compare and swap
  • 如果存在競爭,他的性能甚至比lock都會差,因為你正在不斷的進行提交和重複提交
  • 設計一個既正確又公平的無鎖算法是不可能的,因為在競爭的情況下,有些task很僥倖的commit屌了自己的任務,但是另外的任務還在不斷的嘗試commit


兩者還有一個比較的區別就是一個lock的program當一個線程拿到lock之後可以直接把整個程序都給block, 但是lock-free的程序即使在線程被suspended的情況下,仍然可以運行(通過不斷的retry commmit機制),比如下面的兩端代碼



一種是lock的版本,一種是lock-free的版本,假設我們有100多個線程同時運行,在lock的版本中,線程的運行依賴其他線程的lock的釋放。但是對於Lock-free的版本,所有的線程都可以同步開展,如果一個線程被攔截,只有這個線程的成果不會被共享,但是其他線程仍然可以運行


PS:

  • atomic<int>不一定是lock-free,這個取決於硬體提不提供int級別的atomic, 這也是你可以藉助is_lock_free()來檢查的原因,在整個C++標準庫的實現中,只有std::atomic_flag是被強制要求以lock-free來實現的
關鍵字: