多執行緒的那點兒事16(之無鎖鏈表)

2022-03-24 23:29:28 字數 1307 閱讀 8310

前面,為了使得寫操作快速進行,我們定義了順序鎖。但是順序鎖有個缺點,那就是處理的資料不能是指標,否則可能會導致exception。那麼有沒有辦法使得處理的資料報括指標呢?當然要是這個鍊錶沒有鎖,那就更好了。

針對這種無鎖鏈表,我們可以初步分析一下,應該怎麼設計呢?   

(1)讀操作沒有鎖,那麼怎麼判斷讀操作正在進行呢,只能靠標誌位了;

(2)寫操作沒有鎖,那麼讀操作只能乙個執行緒完成;

(3)寫操作中如果是新增,那麼直接加在末尾即可;

(4)寫操作中如果是刪除,那麼應該先刪除資料,然後等到當前沒有操作訪問刪除資料時,釋放記憶體,但是首節點不能刪除。

普通鍊錶的結構為,

[cpp]view plain

copy

typedef

struct

_link  

link;  

假設此時有32個執行緒在訪問鍊錶,那麼可以定義乙個全域性變數value,每乙個bit表示乙個thread,讀操作怎麼進行呢,

[cpp]view plain

copy

void

read_process()  

那麼,寫操作怎麼進行呢,

[cpp]view plain

copy

void

write_process_add(link* phead, link* plink)  

void

write_process_del(link* phead, link* plink)  

free(plink);  

}  其中鍊錶的刪除操作為,

[cpp]view plain

copy

/**  from:  

*    ->   a  ->  b -> c -> d

**  to:

*        -----------------

*        |               v

*    ->  a        b  ->  c ->d 

*                               

*/總結:

(1)這種無鎖鏈表有很多侷限:多讀少寫、注意使用原子操作、不能刪除頭結點、資料只能新增到尾部、注意刪除順序和方法、讀執行緒個數有限制等等;

(2)寫操作在操作前需要等待所有的讀操作,否則有可能發生異常;

(3)寫操作不能被多個執行緒使用;

(4)無鎖鏈表應用範圍有限,只是特殊情況下的一種方案而已。

多執行緒的那點兒事(之無鎖佇列)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!對於編寫多執行緒的朋友來說,佇列具有天生的互斥性。在佇列裡面,乙個負責新增資料,乙個負責處理資料。誰也不妨礙誰,誰也離不開誰。所以,佇列具有天生的並行性。define max number 1000l define status int defin...

多執行緒的那點兒事14(之無鎖佇列)

對於編寫多執行緒的朋友來說,佇列具有天生的互斥性。在佇列裡面,乙個負責新增資料,乙個負責處理資料。誰也不妨礙誰,誰也離不開誰。所以,佇列具有天生的並行性。cpp view plain copy define max number 1000l define status int define ok 0...

多執行緒的那點兒事(之多執行緒除錯)

軟體除錯是我們軟體開發過程中的重要一課。在前面,我們也討論過程式除錯,比如說這裡。今天,我們還可以就軟體除錯多講一些內容。比如說條件斷點,資料斷點,多執行緒斷點等等。include int value 0 void test int main 1 資料斷點 所謂資料斷點,就是全域性變數或者函式中的數...