C 多執行緒學習 執行緒間的共享資料

2021-07-24 18:43:50 字數 1903 閱讀 1520

多執行緒間的共享資料如果不加以約束是有問題的。最簡單的方法就是對資料結構採用某種保護機制,通俗的表達就是:

確保只有進行修改的執行緒才能看到不變數被破壞時的中間狀態。從其他訪問執行緒的角度來看,修改不是已經完成了,就是還沒開始。

1.使用互斥量保護共享資料

當訪問共享資料前,使用互斥量將相關資料鎖住,再當訪問結束後,再將資料解鎖。c++標準庫為互斥量提供了乙個raii語法的模板類std::lack_guard ,其會在構造的時候提供已鎖的互斥量,並在析構的時候進行解鎖.

#include #include #include std::listsome_list; // 1

std::mutex some_mutex; // 2

void add_to_list(int new_value)

bool list_contains(int value_to_find)

上述例子通過lock_guart使得add_to_list和list_contains這兩個函式對資料的訪問是互斥的。從而保證多執行緒中資料的安全。

2.堤防介面內在的條件競爭

比如你在寫乙個棧的資料結構,並且給棧的push\pop\top\empty\size\等介面增加了互斥保護。看以下**:

stacks;

if (! s.empty())

以上只是單執行緒安全,對於多執行緒在1和2之間,可能有來自另乙個執行緒的pop()呼叫並刪除了最後乙個元素,此時就會出問題。

因為鎖的粒度太小,需要保護的操作並未全覆蓋到。可以考慮適當增大鎖的粒度。

std::shared_ptrpop()

void pop(t& value)

3.堤防死鎖問題

造成死鎖最大的問題是:由兩個或兩個以上的互斥量來鎖定乙個操作。一對執行緒需要對他們所有的互斥量做一些操作,其中每個執行緒都有乙個互斥量,且等待另乙個解鎖。這樣沒有執行緒能工作,因為他們都在等待對方釋放互斥量。

避免死鎖的一般建議,就是讓兩個互斥量總以相同的順序上鎖:總在互斥量b之前鎖住互斥量a,可以有效防止大部分問題。乙個更好的方法是利用c++提供的std::lock,可以一次性鎖住多個互斥量。看以下例子:

class some_big_object;

void swap(some_big_object& lhs,some_big_object& rhs);

class x

friend void swap(x& lhs, x& rhs)

};

呼叫std::lock() ①鎖住兩個互斥量,並且兩個std:lock_guard 例項已經建立好②③,還有乙個互斥量。提供std::adopt_lock 引數除了表示std::lock_guard 物件已經上鎖外,還表示現成的鎖,而非嘗試建立新的鎖。

注意:乙個互斥量可以在同一執行緒上多次上鎖(std::recursive_mutex)。

以下是設計鎖的幾條忠告:

1.盡量避免巢狀鎖,乙個執行緒已獲得鎖時別再獲取第二個

2.避免在持有鎖是呼叫使用者提供的**,因為使用者的**不可預知,有發生死鎖的可能

3.使用固定順序獲取鎖--多於多個鎖時可有效避免死鎖

對於鎖的粒度問題也是需要注意的,大的粒度可以保護更多的資料,但是其對效能的影響也越大。同時需要盡可能他將鎖的持有時間減到最小。

比較操作符一次鎖住乙個互斥量:

friend bool operator==(y const& lhs, y const& rhs)

利用int的拷貝來減少鎖的等待時間,是一種高效的做法。

C 多執行緒共享資料

在多執行緒程式設計中,我們經常要使用資料共享.c 中是如何實現的呢?很簡單,只要把你要共享的資料設定成靜態的就可以了.關鍵字static 如下 static queue q1 new queue static int b 0 在這裡我定義了乙個整形變數b和佇列q1.接下去就可以建立多執行緒 了.如下...

C 多執行緒共享資料

在多執行緒程式設計中,我們經常要使用資料共享.c 中是如何實現的呢?很簡單,只要把你要共享的資料設定成靜態的就可以了.關鍵字static 如下 static queue q1 new queue static int b 0 在這裡我定義了乙個整形變數b和佇列q1.接下去就可以建立多執行緒 了.如下...

C 多執行緒共享資料

在多執行緒程式設計中,我們經常要使用資料共享.c 中是如何實現的呢?很簡單,只要把你要共享的資料設定成靜態的就可以了.關鍵字static 如下 static queue q1 new queue static int b 0 在這裡我定義了乙個整形變數b和佇列q1.接下去就可以建立多執行緒 了.如下...