並行程式設計 併發級別

2021-07-25 16:55:38 字數 1588 閱讀 2729

1.1 wait-freedom 無等待併發

wait-freedom 指的是每乙個執行緒都一直執行下去而無須等待外部條件,整個流程中任何操作都能在乙個有限的步驟內完成,這是最高的併發級別,沒有任何阻塞。

結合之前原子操作部分的知識,可以簡單認為能夠直接呼叫乙個原子操作實現的演算法或程式就屬於wait-free,比如下面的 increment_reference_counter 函式就是wait-free的,它封裝了atomic_increment這個原子自增原語,多個執行緒可以同時呼叫這個函式對同乙個記憶體變數進行自增,而無須任何阻塞(其實也是有阻塞的,是匯流排鎖級別)

與此做對比,cas類的呼叫就不是wait-free的,注意wait-free的原語都不能包含內部迴圈,cas原語使用時通常包含在「迴圈直到成功」的迴圈內部。

void increment_reference_counter(rc_base* obj)

atomic_increment(obj->rc);
1.2 lock-freedom 無鎖併發

lock-freedom 指的是整個系統作為乙個整體一直執行下去,系統內部單個執行緒某段時間內可能會飢餓,這是比wait-freedom弱的併發級別,但系統整體上看依然是沒有阻塞的。所有wait-free的演算法顯然都滿足lock-free的要求。

lock-free演算法通常可以通過同步原語 cas實現。

void stack_push(stack* s, node* n)

node* head;

dowhile ( ! atomic_compare_exchange(s->head, head, n));

多個執行緒同時呼叫上述函式,理論上某個執行緒可以一直困在迴圈內部,但一旦有乙個執行緒原子操作失敗而返回迴圈,意味著有其他執行緒成功執行了原子操作而退出迴圈,從而保證系統整體是沒有阻塞的。

其實前面的原子自增函式也可以用下面的原語實現,在這種實現裡,不再是所有執行緒都無阻塞了,某些執行緒可能會因為cas失敗而迴繞若干次迴圈。

void increment_reference_counter(rc_base* obj)

int rc;

do while(!atomic_compare_exchange(obj->rc,rc,rc+1));

1.3 obstruction-freedom 無阻塞併發

obstruction-free 是指在任何時間點,乙個孤立執行執行緒的每乙個操作可以在有限步之內結束。只要沒有競爭,執行緒就可以持續執行,一旦共享資料被修改,obstruction-free 要求中止已經完成的部分操作,並進行回滾,obstruction-free 是併發級別更低的非阻塞併發,該演算法在不出現衝突性操作的情況下提供單執行緒式的執行進度保證,所有 lock-free 的演算法都是 obstruction-free 的。

1.4 blocking algoithms 阻塞併發

阻塞類的演算法是併發級別最低的同步演算法,它一般需要產生阻塞。可以簡單認為基於鎖的實現是blocking的演算法。詳細參考第五章

上述幾種併發級別可以使用下圖描述:

藍色是阻塞的演算法,綠色是非阻塞演算法,金字塔越上方,併發級別越高,效能越好,右邊的金字塔是實現工具(原子操作、鎖、互斥體等)

34 併發程式設計 併發並行

一 併發 無論是並行還是併發,在使用者看來都是 同時 執行的,不管是程序還是執行緒,都只是乙個任務而已,真是幹活的是cpu,cpu來做這些任務,而乙個cpu同一時刻只能執行乙個任務。併發 是偽並行,即看起來是同時執行。單個cpu 多道技術就可以實現併發,並行也屬於併發 二 並行 並行 並行 同時執行...

java併發程式設計 並行和併發(1)

1.為什麼需要並行?效能 在多核cpu提高效能業務需求 平行計算還出於業務模型的需要 並不是為了提高系統效能,而是確實在業務上需要多個執行單元。比如http伺服器,為每乙個socket連線新建乙個處理執行緒 讓不同執行緒承擔不同的業務工作 簡化任務排程 2.概念 同步 synchronous 和非同...

c 併發程式設計 01 併發與並行

並行 parallel 指在同一時刻,有多條指令在多個處理器上同時執行。所以無論從微觀還是從巨集觀來看,二者都是一起執行的。併發 concurrency 指在同一時刻只能有一條指令執行,但多個程序指令被快速的輪換執行,使得在巨集觀上具有多個程序同時執行的效果,但在微觀上並不是同時執行的,只是把時間分...