主要內容:
如果一種資料結構可以被多個執行緒所訪問,其要不就是絕對不變的(其值不會發生變化,
並且不需同步),要不程式就要對資料結構進行正確的設計,以確保其能在多執行緒環境下能夠
(正確的)同步。一種選擇是使用獨立的互斥量,其可以鎖住需要保護的資料,另一種選擇是設計一種能夠併發訪問的資料結構。第一種使用互斥量,在同一時間只有乙個執行緒可以訪問資料,實際是一種序列的序列化訪問。顯示的組織了多執行緒對資料結構的併發訪問。
所以,縮小保護區域,減少序列化訪問,就能提高併發。允許執行緒併發讀取的資料結構並不少見,而對資料結構的修改,必須是單執行緒獨立訪問。所以不可能完全實現併發,只能讓序列化訪問最小化。
一、基於鎖的併發資料結構
基於鎖的併發資料結構設計,需要確保訪問執行緒持有鎖的時間最短。都是在保證資料結構是執行緒安全的前提下。在設計資料結構,考慮以下問題:
1、使用鎖實現乙個執行緒安全的棧
1 #include 2struct
empty_stack: std::exception3;
6 template7
classthreadsafe_stack
8
14 threadsafe_stack(const threadsafe_stack&other)
1519 threadsafe_stack& operator=(const threadsafe_stack&) =delete;
20
void
push(t new_value)
21
25 std::shared_ptrpop()
2634
void pop(t&value)
3541
bool empty() const
4246 };
執行緒安全佇列——使用鎖和條件變數
執行緒安全佇列——使用細粒度鎖和條件變數
(參考《併發程式設計》,先佔坑以後補上沒有實戰經驗看不太懂)
二、使用鎖設計更加複雜的資料結構
編寫乙個使用鎖的執行緒安全查詢表
編寫乙個使用鎖的執行緒安全鍊錶
基於鎖的併發資料結構
可以使用細粒度的鎖來減小佇列的臨界區,這裡使用了乙個dummy node用來進一步減小鎖的臨界區。若要判斷佇列是否為空,只需要執行下述判斷 head.get get tail 請注意,因為在進行push的時候需要修改tail,所以對tail的訪問和修改都需要進行加鎖。這裡使用get tail來封裝這...
第6章 設計基於鎖的併發資料結構
為併發設計資料結構是為了多個執行緒可以同時更好的使用此結構 設計併發資料結構的準則是什麼 保證黨資料結構不變性被別的執行緒破壞時的狀態不被任何別的執行緒看到。意味著當要在併發中修改此結構中的部分資料時 即資料結構的不變性被破壞 應當通過新增互斥元的方法阻止其他訪問該資料的執行緒訪問 破壞的狀態不被別...
c 併發程式設計(六) 基於鎖的併發資料結構設計
在我們進行併發程式設計的時候,如果多執行緒使用到了資料結構,那麼程式設計過程中需要保證此資料結構的正確同步。有兩種方法 1 選擇單獨的互斥元與外部鎖來保護資料 2 設計乙個可以同時訪問的資料結構 其中前幾節我們涉及到了第一種方法,現在我們重點描述下第二種方法。使用鎖和條件變數的執行緒安全佇列 tem...