C 併發程式設計(七) 同步操作與強制排序

2021-09-11 19:38:49 字數 1560 閱讀 4689

「同步發生」關係是指:只能在原子型別之間進行的操作。例如對乙個資料結構進行操作(對互 斥量上鎖),如果資料結構包含有原子型別,並且操作內部執行了一定的原子操作,那麼這些操作就是同步發生關係。

「先行發生」關係是乙個程式中,它指定了某個操作去影響另乙個操作。對於單執行緒來說,如果原始碼中操作a發生在操作b之前,那麼a就先行與b發生。

假設你有兩個執行緒,乙個向資料結構中填充資料,另乙個讀取資料結構中的資料。為了避免惡性條件競爭,第乙個執行緒設定乙個標誌,用來表明資料已經準備就緒,並且第二個執行緒在這個標誌設定前不能讀取資料。

#include #include #include std::vectordata;

std::atomicdata_ready(false);

void reader_thread()

std::cout<<"the answer="《當寫入資料完成之後,data_ready就會作為訊號,通知讀取程序可以工作了。

當儲存操作被標記為memory_order_release,memory_order_acq_rel或memory_order_seq_cst,載入被標記為memory_order_consum,memory_order_acquire或memory_order_sqy_cst,並且操作鏈上的每一載入操作都會讀取之前操作寫入的值,因此鏈上的操作構成了乙個釋放序列(release sequence),並且初始化儲存同步(對應memory_order_acquire或memory_order_seq_cst)或是前序依賴(對應memory_order_consume)的最終載入。

#include #include std::vectorqueue_data;

std::atomiccount;

void populate_queue()

void read_y_then_x()

int main()

釋放柵欄②與獲取柵欄⑤會進行同步。在①處儲存x先行於⑥處載入x,最後x讀取出來必為true,並且斷言不會被觸發⑦。如果不使用柵欄,x和y的賦值順序就會被隨機重排,會發生y=true,x=false的情況被執行緒b讀取。

雖然,柵欄同步依賴於讀取/寫入的操作發生於柵欄之前/後,但是這裡有一點很重要:同步點,就是柵欄本身。假如你使用了下面的**

void write_x_then_y()

這裡裡的兩個操作,就不會被柵欄分開,並且也不再有序。只有當柵欄出現在儲存x和儲存y操作之間,這個順序是硬性的。

#include #include #include bool x=false;  // x現在是乙個非原子變數

std::atomicy;

std::atomicz;

void write_x_then_y()

void read_y_then_x()

int main()

當你使用乙個普通的非原子bool型別來替換原子的x,行為和替換前完全一樣。②中的儲存和③中對y的載入,都必須是原子操作;否則,將會在y上產生條件競爭,不過一旦讀取執行緒看到儲存到y的操作,柵欄將會對x執行有序的操作。

併發程式設計(4)同步併發操作

一 主要涉及 等待事件 帶有期望的等待一次性事件 在限定時間內等待 使用同步操作簡化 二 等待乙個條件或者事件 1 選擇是在等待執行緒在檢查間隙,使用 std this thread sleep for 進行週期性的間歇 2 也是優先的選擇 是,使用c 標準庫提供的工具去等待事件的發生。通過另一線程...

作業系統 併發 互斥與同步

在多道程式設計系統種,程序會被交替執行,進而在巨集觀上表現出一種併發的外部特徵。為什麼需要併發?假設乙個支援單使用者的單處理器多道程式設計系統,使用者可以從乙個應用程式切換到另乙個應用程式,每個應用程式都使用同一鍵盤輸入,使用同一鍵盤輸出。由於每個程式都需要使用某乙個輸入輸出過程,所以將他視為乙個共...

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

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