c 11多執行緒庫

2021-07-02 03:28:47 字數 4655 閱讀 6748

建立執行緒的四種方法:

執行緒類的建構函式是變參建構函式,第乙個引數是執行緒函式,後面的引數為執行緒函式的引數(引數通過值傳遞方式,若要引用傳遞須加std::ref())。

thread   t1 (counter, 1, 6);   //void counter(int, int);

//class counter 實現 operator()

1) thread   t1;   //c++統一推薦方法

2) counter    c(1, 20);

thread   t2(c);

3) thread   t3(counter(1,20));

比較第一種和第三種構造方式,如果函式物件的建構函式不需要任何引數。 thread  t3(counter());是不行的,因為編譯器會認為你在宣告乙個函式,函式名為t3,此時只能用第一種構造方式。

thread   t1 ((int, int), 1, 6); 

// class counter  c();

thread   t;

一般常見的是乙個類自己建立乙個後台處理執行緒:thread   t;

執行緒本地儲存 thread_local

thread_local    int   n;多執行緒程式設計經常需要操作共享的記憶體,在讀/寫過程中會導致競爭條件。

例如:int   counter = 0;

++counter;  //因為++counter不時原子操作,多個執行緒中出現此操作時不是執行緒安全的。

應該用:

atomiccounter(0);  //等效於 atomic_int   counter(0);

++counter;  //此時多個執行緒執行++counter是乙個原子操作,是執行緒安全的。

例:

void func( std::atomic&counter)

intmain()

);  

for( auto&t : threads )

t.join();    

//呼叫join,如果執行緒未結束,則main函式阻塞於此。

std::count

<<"

result=

"return0;

}/*join的呼叫會導致呼叫執行緒阻塞於此,若不希望呼叫執行緒阻塞,但又想知道被調執行緒是否結束,應當用其它方式,例如訊息...

*/

編寫多執行緒必須分外留意操作順序,如果無法避免執行緒共享資料,則必須提供同步機制,保證一次只有乙個執行緒能更改資料。使用互斥解決競爭條件,可能導致死鎖。

1) 非定時互斥體類std::mutex         std::recursive_mutex

lock() : 嘗試獲取鎖,並且阻塞直到獲取鎖。

try_lock() : 嘗試獲取鎖,並立即返回,成功獲取返回true,否則false。

unlock() : 釋放鎖。

mutex與recursive_mutex的區別在於,前者已經獲得所後不得再嘗試獲取,這會死鎖,後者能遞迴獲取,注意釋放次數應與獲取次數相等。

2) 定時互斥鎖類std::timed_mutex     std::recursive_timed_mutex

lock() ,      try_lock() ,        unlock()

try_lock_for(rel_time) : 指定相對時間內獲得返回true, 超時返回false。

try_lock_until(abs_time) : 指定系統絕對時間內獲得返回true, 超時返回false。

timed_mutex與recursive_timed_mutex區別同上。

鎖類是乙個包裝器,析構函式會自動釋放關聯的互斥體。

1) 簡單鎖std::lock_guard

其建構函式會要求獲得互斥體,並阻塞直到獲得鎖。

2) 複雜鎖std::unique_lock 

explict   unique_lock( mutex_type&   m); //

阻塞直到獲得鎖。

unique_lock(mutex_type& m, defer_lock_t) noexcept; //

儲存乙個互斥體引用,不會立即嘗試獲得鎖。鎖可以在以後獲得。

unique_lock(mutex_type& m, try_to_lock_t); //

嘗試獲得引用的互斥鎖,未能獲得也不阻塞。

unique_lock(mutex_type& m, adopt_lock_t); //

該鎖假定執行緒獲得引用的互斥鎖,並負責管理這個鎖。

template

unique_lock(mutex& m, const chrono::time_point& abs_time); //

嘗試獲取該鎖,直到超過給定的絕對時間。

template

unique_lock(mutex& m, const chrono::duration& rel_time); //

嘗試獲取該鎖,直到超過給定的相對時間。

unique_lock類還支援lock(), try_lock(), try_lock_for(), try_lock_until()等方法。

通過owns_lock()檢視是否獲得了這個鎖;也可以用if對unique_lock物件直接判斷是否獲得鎖,因為它定義了bool()運算子。

1) 泛型lock可變引數模板函式

template

void  lock(l1&,  l2&,  l3&...);

按順序鎖定,如果乙個互斥體丟擲異常,會對已獲得的鎖unlock。

2) 泛型try_lock

template

int  try_lock(l1&,  l2&,  l3&...);

通過順序呼叫互斥體物件的try_lock,成功返回-1,失敗返回從0開始的位置索引,並對已獲得的鎖unlock。

引數順序每次應保持一致, 否則易死鎖。

保證call_once排程的函式只被執行一次。

//

1. 簡單鎖

mutex mmutex;

lock_guard

mlock(mmutex);

//2. 定時鎖

timed_mutex mtimemutex;

unique_lock

mlock(mtimedmutex, chrono::milliseconds(200

));//

3. 泛型

mutex mut1;

mutex mut2;

unique_lock

lock1(mut1, defer_lock_t());

unique_lock

lock2(mut2, defer_lock_t());

lock

(lock1, lock2);

//4. 雙重檢查鎖定演算法 (代替call_once的用法)

class

myclass

private

:

int *p;

}myclass

var;

bool initialized = false

;mutex mut;

void

func()

}cout

<<"ok"

<兩次檢查initialized。獲得鎖之前和獲得鎖之後,確保init只呼叫一次。

notify_one();  //

喚醒等待這個條件變數的執行緒之一

notify_all(); //

喚醒所有等待這個條件變數的執行緒 //

1)前提是已經獲得lk的鎖 //

2)呼叫wait會unlock lk,然後等待 //

3)當被喚醒後 lock lk

wait( unique_lock&lk);

wait_for(unique_lock

& lk, const chrono::duration&rel_time);

wait_until(unique_lock

&lk, const chrono::time_point& abs_time);

//

例:向佇列中加入資料,當佇列不為空時,後台執行緒被喚醒處理資料

std::queuestring>mqueue;

std::mutex mmutex;

std::condition_variable mcondvar;

//向佇列加入資料的執行緒

unique_locklock

(mmutex);

mqueue.push( data);

mcondvar.notify_all();

//後台處理資料的執行緒

unique_locklock

(mmutex);

while(true

)

promise/future模型方便獲取執行緒返回的結果、執行緒間通訊、處理異常

C 11 多執行緒

新特性之描述 雖然 c 11 會在語言的定義上提供乙個記憶體模型以支援執行緒,但執行緒的使用主要將以 c 11 標準庫的方式呈現。c 11 標準庫會提供型別 thread std thread 若要執行乙個執行緒,可以建立乙個型別 thread 的實體,其初始引數為乙個函式物件,以及該函式物件所需要...

c 11 多執行緒

1.多執行緒的原理 同一時間內,cpu只能處理1條執行緒,只有1條執行緒在工作 執行 多執行緒併發 同時 執行,其實是cpu快速地在多條執行緒之間排程 切換 如果cpu排程執行緒的時間足夠快,就造成了多執行緒併發執行的假象。思考 如果執行緒非常非常多,會發生什麼情況?cpu會在n多執行緒之間排程,c...

C 11 多執行緒

2011 年 c 迎來重大的改革 語言層面上承認了 多執行緒 程式的存在 加入了 thread 多執行緒支援庫,內容豐富 功能強大。首先從我個人理解角度粗鄙的理解一下多執行緒。多執行緒眾所周知 切割時間片的多程式併發執行,大多數的計算機都支援多執行緒併發的硬體支援。這可能是最簡單的多執行緒程式了。多...