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

2021-10-02 18:39:13 字數 4095 閱讀 2699

繼續記錄鎖的一些概念,眼瞅著疫情的拐點即將出現了。

unique_lock

unique_lock這個是可以取代前一篇寫的lock_guard,在第二個引數的為adopt_lock時與之前一樣,表示unique_lock物件已經繫結了互斥量,提前lock互斥量,不用自己去unlock了,其實不建議搞這些花裡胡哨的,lock和unlock對稱使用貌似還清楚一點。

使用方法就是直接將lock_guard換成unique_lock

#include

#include

#include

#include

using

namespace std;

classa}

void

outcommand()

else}}

private

: list<

int> ticket;

mutex mylock1;

mutex mylock2;};

intmain

(int argc,

char

*ar**)

完全替換那要他有何用,存在即合理,設想一下,執行緒一拿到鎖後要執行好長一段時間,執行緒二在等這個鎖,難道他就這麼一直等下去麼,所以unique_lock的作用就體現出來,

try_to_lock引數,表示嘗試去鎖,如果沒有鎖定成功那麼就可以去執行別的程式,並不會一直處於等待狀態。

**的寫法如圖所示:

unique_lock

myunique

(mymutex, try_to_lock);if

(myunique.

own_lock()

)else

defer_lock引數,這個引數就是表示初始化了乙個沒有加鎖的mutex,需要自己加鎖,互斥量的解鎖,到生命週期結束後自動結束。或者自己中途解鎖也行。

2 成員函式release();

返回指向mutex指標,並解除物件與mutex的繫結,並通過指標進行呼叫解鎖函式。

使用方法如圖所示:

unique_lock

myunique

(mymutex, try_to_lock)

;//定義乙個該型別指標

mutex *ptx = myunique.

release()

;ticket.

push_back

(i);

ptx-

>

unlock()

;

或者通過移動語義move換個物件繫結

例如:

unique_lock

myunique

(mymutex)

;unique_lock

myunique2

(move

(myunique));

//定義乙個指標

mutex *ptx = myunique2.

release()

;ticket.

push_back

(i);

ptx-

>

unlock()

;

3.鎖的粒度這個是乙個概念,鎖住的**少,那麼鎖的粒度就細,執行效率就越高

鎖住的**多,那麼鎖的粒度就粗,執行效率就越低,根據情況選擇適合的粒度,當然了,這概念我也只是聽到,沒有實際的體驗,先記下再說。

單例模式

這裡順便記錄一下單例模式,之前一直模模糊糊不太懂,面試基本這個問題回答不上來。

單例模式:在整個任務中,有一些特殊的類,在程式裡只能建立乙個物件,

先放上**:

```cpp

#include

using

namespace std;

class

myclass

;private

:static myclass *myptr;

public

:static myclass *

getinstance()

return myptr;

}void

myprint()

};myclass *myclass::myptr =

null

;int

main

(int ar**,

char

*argc)

執行結果如圖所示:

建構函式的私有化,防止新建多個物件,指標所指向的物件唯一,並且靜態表示不屬於任何乙個物件,屬於類。此時**的myptr1和myptr2所指向的位址是乙個位址。

但這裡你會發現兩個問題,

一:new和delete是成對出現的,這個程式就不完美。

二:如果是兩個執行緒進行new 物件,那麼會出現執行緒一未完成new物件,進行到一半,而時間片轉到執行緒二時,此時他又可以new乙個,因為執行緒一未完全結束new物件,這樣的話程式就可以產生兩個new物件了,不符合單例模式的要求,因此借鑑案例分別引入

類中類,建立物件,然後推出程式的時候自動執行析構函式,函式中新增delete指標和互斥量的方法,執行緒進行加鎖的方式進行互斥訪問。

方法如圖所示:

#include

#include

#include

using

namespace std;

mutex mymutex;

class

myclass

;private

:static myclass *myptr;

public

:static myclass *

getinstance()

}return myptr;

}class

delclass}}

;void

myprint()

};myclass *myclass::myptr =

null

;void

myfunc()

intmain

(int ar**,

char

*argc)

執行結果顯示,正確無異常,且在程式退出後顯示delete指標。

後來了解到,c++11提供了乙個函式call_once();可以代替這個只執行一次的new物件這個操作,以及增加引數互斥標誌,就是全給你搞好了。

#include

#include

#include

using

namespace std;

mutex mymutex;

once_flag myflag;

class

myclass

;private

:static myclass *myptr;

public

:static

void

singlecreate()

static myclass *

getinstance()

// }

return myptr;

}class

delclass};

void

myprint()

};myclass *myclass::myptr =

null

;void

myfunc()

intmain

(int ar**,

char

*argc)

可以看到,結果與上述**一樣,可以單換。

留乙個問題算了,getinstance為啥是指標返回,不是引用返回和值返回

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

疫情確診人數連續12天下降,終將結束,然鵝還是處於不能出門狀態,繼續記筆記吧。條件變數 condition variable 假設有兩個執行緒就是前篇記錄的放佇列資料線程,和讀佇列資料線程,條件變數就是乙個條件類,等待乙個條件達成即執行 執行成員函式wait 等待另乙個執行緒執行notify one...

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沒有...