本文首發於: 掘金
對於初次接觸線程同步的前端來講,老是對互斥鎖、條件變量、信號量等術語傻傻分不清楚,這裏根據本身的理解簡單作下總結,若有疏漏之處,歡迎你們批評指正。前端
在多線程環境中每每存在因某一資源被同時訪問致使該資源不一致的問題,互斥鎖
經過排它性,即同時只容許一個訪問者對其進行訪問來保證資源的有效同步,但它沒法限制線程對該資源的訪問順序,所以線程對資源的訪問也是無序的。多線程
在互斥鎖
中,若是線程 A 在請求鎖的時候發現該鎖已被線程 B 霸佔,那麼此時線程 A 便會進入休眠狀態,直到鎖被線程 B 釋放後被系統喚醒。但在自旋鎖
中,線程 A 在發現鎖被霸佔時並不進入休眠,而是一直循環查看鎖的持有者是否已經釋放了該鎖。初看起來,這種霸佔CPU資源的作法極其低效,但與互斥鎖
仔細對比後咱們能夠發現它有如下幾個優勢:post
互斥鎖
休眠、喚醒所涉及的一系列上下文切換、CPU搶佔等各類複雜流程。固然,上面的高效也是有條件的,因爲它佔用CPU資源,因此它主要適用於如下場景:學習
遞歸鎖
又叫可重入鎖
,與 互斥鎖
的主要區別是在同一個線程內能夠屢次得到鎖資源,別的線程必須等待該線程釋放相應次數的鎖才能得到,其主要目的是爲了解決同一進程內的死鎖問題,但在不一樣的線程中,它與互斥鎖
並無什麼區別。線程
上面介紹的互斥鎖
、自旋鎖
、遞歸鎖
都屬於排它鎖,即一個線程得到鎖資源後,其餘線程必須等待直到該鎖被釋放。但在某些讀多寫少的狀況下,這樣的機制不免有些低效,所以讀寫鎖
就是爲解決這樣的問題而誕生的。讀寫鎖分讀鎖和寫鎖,其特色以下:3d
條件變量
主要適用於一個線程須要等待某個共享資源知足某個條件後進行一系列同步操做的場景。它主要包含:code
它通常與互斥鎖
配合使用(主要用來保護共享資源),在等待線程中,若是條件不成立,該線程會自動阻塞,並釋放掉等待狀態改變的互斥鎖,若是信號發送線程改變了條件,它發送信號給關聯的條件變量,並喚醒等待線程,等待線程從新得到互斥鎖,從新評估條件。遞歸
信號量
主要適用於一個線程須要等待另一個個線程完成一些操做後再繼續執行本身操做的場景,它與上面各類鎖的最大區別是:進程
信號量
要解決的是線程之間任務同步問題。信號量
能夠經過一個線程中獲得,在另外一個線程中釋放。認真回味下咱們會發現信號量
要解決的問題也可使用條件變量
來處理,相對於信號量
,條件變量
主要有如下不足:資源
條件變量
須要藉助全局共享變量以及互斥鎖
來達到狀態的檢測。條件變量
適用於多線程環境,沒法適用於多進程環境。屏障
是一種協調多個線程進行工做,即容許某個線程等待直到全部的合做線程達到某一個條件,而後從該條件下繼續執行的同步機制。
本文對線程同步中所涉及到的術語的特色及適用場景進行了簡單的總結,若是你在閱讀過程當中發現任何錯誤,歡迎留言指正,咱們一塊兒學習一塊兒進步。^ _ ^