C 11的多執行緒併發程式設計(五)

2021-10-02 21:17:29 字數 3652 閱讀 4161

疫情確診人數連續12天下降,終將結束,然鵝還是處於不能出門狀態,繼續記筆記吧。。。

條件變數 condition_variable

假設有兩個執行緒就是前篇記錄的放佇列資料線程,和讀佇列資料線程,條件變數就是乙個條件類,等待乙個條件達成即執行**。執行成員函式wait()等待另乙個執行緒執行notify_one()的成員函式。那麼wait()這行**才會被喚醒,如下:

#include

#include

#include

#include

using

namespace std;

classa}

void

outcommand()

);int command = ticket.

front()

; ticket.

pop_front()

; cout <<

"command is :"

<< command << endl;}}

private

: list<

int> ticket;

mutex mylock;

condition_variable mycond;};

intmain

(int argc,

char

*ar**)

當寫執行緒執行notify_one()**時,將原本wait的**喚醒,wait就開始執行,

首先去獲取鎖,如果沒有就等待,有的話,開始判斷lambda表示式,如果返回false那就釋放鎖,繼續等待,如果返回的是true,那麼就繼續往下執行下面**。

當有多個執行緒需要讀取這個命令是什麼去執行其他操作,那就可以令寫程序執行mycond.notify_all();去通知所有讀程序去喚醒wait().

async

async是乙個函式模板,通常是啟動乙個非同步任務,即建立乙個執行緒,並執行對應的執行緒入口函式,返回乙個future物件。future是乙個類模板,那麼我建立乙個它的物件去接async非同步任務返回的物件,再去呼叫成員函式get()即可以獲得函式返回值。

#include

#include

#include

using

namespace std;

intmyfunc()

intmain()

async引數預設是std::launch::async,在呼叫async函式的時候就開始建立執行緒了,還有乙個引數是std::launch::deferred,表示延遲呼叫,並不會建立新的執行緒。

std::packaged_task

這個是類模板,將可呼叫物件包裝起來,然後作為執行緒入口函式使用。使用方法如圖所示:

#include

#include

#include

using

namespace std;

intmyfunc

(int value)

intmain()

也可以使用向量vector來操作,例如:

vector int(

int)

>> mytask;

package_task<

int(

int)

>

mypackage

(myfunc)

;mytask.

push_back

(move

(mypackage));

//此時mypackage已經失效了

package_task<

int(

int)

> mypackage2;

auto iter = mytask.

begin()

;mypackage2 =

move

(*iter)

;mytask.

erase

(iter)

;//iter已經失效了該刪除了

mypackage2(99

);future <

int> myfuture = mypackage2.

get_future()

;cout << myfuture.

get(

)<< endl;

或者使用lambda表示式來解決

packaged_task<

int(

int)

mypackage([

](int value));

//乙個是int返回值,乙個是int引數

thread mythread

(std::

ref(mypackage)

,100);

//因為packaged_task是乙個類模板,所以保證是同乙個物件,採用移動語義。

mythread.

join()

; future<

int> myfuture = mypackage.

get_future()

; cout << myfuture.

get(

)<< endl;

return

0;

效果等價於上方

std::promise

這也是乙個類模板,如果在乙個執行緒中給他賦值,那麼我們可以在另外乙個執行緒中將他取出來用。使用方法如下:

#include

#include

#include

void

myfunc1

(std::promise &mypromise,

int value)

void

myfunc2

(std::future<

int>

&myfuture)

intmain()

future目前執行狀態

future_status status有三種狀態,一種是timeout 表示還沒有執行完,一種是ready就表示已經執行完了,還有一種是deferred,這種情況下一般用在使用async函式,同時第乙個引數被設定為launch::deferred,當status表示deferred表示目前執行緒處於延遲狀態。

shared_future

當在另外乙個執行緒執行get()獲取future存的值,如果再次執行get()則會報異常,因為get函式同時也表示移動的意思,shared_future用來解決這個問題:**圖下:

#include

#include

#include

void

myfunc1

(std::promise &mypromise,

int value)

void

myfunc2

(std::shared_future<

int>

&myfuture)

intmain()

```

C 11的多執行緒併發程式設計(五)

繼續記錄鎖的一些概念,眼瞅著疫情的拐點即將出現了。unique lock unique lock這個是可以取代前一篇寫的lock guard,在第二個引數的為adopt lock時與之前一樣,表示unique lock物件已經繫結了互斥量,提前lock互斥量,不用自己去unlock了,其實不建議搞這...

C 11併發程式設計 多執行緒std thread

c 11引入了thread類,大大降低了多執行緒使用的複雜度,原先使用多執行緒只能用系統的api,無法解決跨平台問題,一套 平台移植,對應多執行緒 也必須要修改。現在在c 11中只需使用語言層面的thread可以解決這個問題。所需標頭檔案 thread noexcept 乙個空的std thread...

C 11 多執行緒 併發程式設計總結

建立std thread,一般會繫結乙個底層的執行緒。若該thread還繫結好函式物件,則即刻將該函式執行於thread的底層執行緒。執行緒相關的很多預設是move語義,因為在常識中線程複製是很奇怪的行為。joinable 是否可以阻塞至該thread繫結的底層執行緒執行完畢 倘若該thread沒有...