鎖使用的一些筆記

2021-09-27 01:34:52 字數 1692 閱讀 6802

-v0.1 2019.8.11 sherlock init

-v0.2 2019.8.24 sherlock finish

在linux系統下程式設計的時候,當需要保護特性資料結構的時候會用到各種鎖。本文記錄作者

在實際使用時候的一些心得。

使用的場景

當乙個資料結構有多個併發的流程去訪問的時候,可以加鎖去做互斥,這樣資料的

一致性的到保護。併發流程有多種表現形式,比如在linux核心裡,核心執行緒,中斷,

來自使用者態的系統呼叫等都可以併發起來; 使用者態的話, 各個執行緒,訊號(訊號處理

函式裡不能使用鎖)可以併發。

加鎖其實就是多個執行流在臨界區外排隊(這裡不考慮try鎖,就是那種試一下可以加上

就加鎖,不可以加上當場就返回的鎖)。我們也可以給臨界區配置乙個原子變數標記,

每個執行流在先搶到這個標記才可以操作保護的資料結構, 操作完保護的資料結構,

退出臨界區的時候釋放這個標記。原子變數標記的方式,其實是用try鎖去保護相應的

資料結構。但是try鎖沒有了排隊等待,需要在加鎖失敗時做必要的處理。

使用時注意的事項

thread1        thread2

lock1 lock2

[...] [...]

lock2 lock1

如上,thread1加了lock1,執行下面的**,thead2加了lock2。這時, thread1想

要加lock2,但是加不上,thread2想要加lock1的,但是也加不上。

同乙個執行流重複加一把鎖也會帶來死鎖:

thread1

lock1

lock1

[...]

使用鎖的時候要注意鎖的不同種類,一般有spinlock和mutex,他們都有對應的讀寫

鎖的版本。一般情況我們可以先不用讀寫鎖,直到確實是效能瓶頸, 我們才去做優化。

spinlock是死迴圈等待獲取鎖的,mutex在獲取鎖失敗後會sleep, 直到可以得到鎖。

所以在不可以sleep的場景裡,我們要用spinlock鎖, 和mutex比較,spinlock不sleep,

所以,spinlock也適用於臨界區很短的加鎖保護。

除錯鎖相關**

一般我們寫好linux核心裡所相關的**,可以開啟核心裡死鎖檢測:

hange檢測: kernel hacking —> debug lockups and hangs

死鎖檢測會檢測出潛在的死鎖位置,然後輸出報告。

hange檢測在超出配置的超時時間後會把呼叫棧打出來。

不過這些檢測開啟後會對系統效能有較大的影響,這些配置只能在除錯版本裡開啟。

(to do: 使用者態死鎖檢測的工具)

加鎖後相關的效能問題

為了維護併發訪問的資源,所以需要加鎖。所以,加鎖之後有可能帶來的效能下降,

本質上是各個執行流相互等待帶來的開銷。所以,要提高效能,還是要把各個執行流的

相互依賴解開。

加鎖對構架演進的影響

鎖臨界區太大,會對後續新增新的鎖進來產生影響,比較容易造成各種死鎖問題。

鎖的實現

(to do: spinlock, q spinlock, 原子變數簡單實現spinlock, mutex)

鎖的一些概念

作業需要乙個目標之前分配目標,這樣在用目標是不用再等,可保證完成所需功能,這叫目標的分配。可用alcobj命令預先分配目標,用dlcobj解除分配 目標是根據要他們做什麼來分配的 讀或者修改 和他們是否可以共享。檔案和成員總是以 shrrd來分配。而資料用規定所狀態來分配鎖的級別。鎖狀態標誌使用的目...

鎖的一些概念

使用reentrantlock獲取鎖的時候會判斷當前執行緒是否為獲取鎖的執行緒,如果是則將同步的狀態 1 釋放鎖的時候則將狀態 1。只有將同步狀態的次數置為 0 的時候才會最終釋放鎖。使用reentrantreadwritelock,同時維護一對鎖 讀鎖和寫鎖。當寫執行緒訪問時則其他所有鎖都將阻塞,...

js的一些使用筆記

重新整理當前頁面 window.location.reload 跳轉到其他頁面 jquery ajax 寫法 ajax success function data 彈窗延時自動關閉小工具 layer 2.使用 layer.msg 彈窗 延遲兩秒關閉 參考 效果如圖 模板引擎thymeleaf無法識別...