最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++在多線程中使用condition_variable實(shí)現(xiàn)wait

 更新時間:2022年09月20日 09:12:32   作者:君子以閱川  
這篇文章主要介紹了C++中的condition_variable中在多線程中的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

前言

有這樣的需求

一個線程需要等待另一個線程執(zhí)行完畢之后它才會繼續(xù)向下執(zhí)行,這該如何實(shí)現(xiàn)? condition_variable類中實(shí)現(xiàn)了wait方法

wait()

  • 可以接受兩個參數(shù),其中第一個參數(shù)是鎖對象,第二個參數(shù)是lambda表達(dá)式,其中的lambda表達(dá)式的返回值要是bool類型
  • 也可接受一個參數(shù),僅僅接受鎖對象
#include<iostream>
#include<mutex>
#include<list>
#include<thread>
using namespace std;
class Obj
{
private:
	list<int> myList;
	condition_variable var;
	mutex tex;
public:
	bool popFromList(int & comb)
	{
		if (!myList.empty()) {
			unique_lock<mutex> cur(tex);
			if (!myList.empty())
			{
				comb = myList.front();
				myList.pop_front();
				return true;
			}
		}
		return false;
	}
	void inToList()
	{
		for (int i = 0; i < 100; i++)
		{
			unique_lock<mutex> cur(tex);
			myList.push_back(i);
			cout << this_thread::get_id() << "正在向list中添加數(shù)據(jù)>; " << i << endl;
			var.notify_one();
		}
	}
	void outFromList()
	{
		while(true)
		{
			unique_lock<mutex> cur(tex);
			var.wait(cur, [this] {
				if (!myList.empty())
					return true;
				return false;
				});
			int comb = myList.front();
			myList.pop_front();
			cout << this_thread::get_id() << "正在取出數(shù)據(jù)>: " << comb << endl;
		}
	}
};
int main()
{
	Obj obj;
	thread thread1(&Obj::outFromList, &obj);
	thread thread2(&Obj::inToList, &obj);
	thread1.join();
	thread2.join();
	cout << "這里是主線程" << endl;
}

線程1執(zhí)行到wait函數(shù)時,會執(zhí)行l(wèi)ambda表達(dá)式

返回值為false時,這個線程就會將鎖打開,將該線程壓入到棧中,執(zhí)行下一個線程 下一個線程執(zhí)行完畢之后執(zhí)行notify_one后就會返回到該線程,繼續(xù)執(zhí)行l(wèi)ambda表達(dá)式

返回值為true時就嘗試獲得鎖

獲得鎖后繼續(xù)執(zhí)行下面的語句

沒有獲得鎖就繼續(xù)卡在wait等待獲取到鎖

返回值為false時,繼續(xù)將鎖打開,線程壓入棧,執(zhí)行下一個線程

返回值為true時,線程繼續(xù)執(zhí)行

運(yùn)行結(jié)果可能是一個線程執(zhí)行完畢另一個線程再執(zhí)行

這不就是順序執(zhí)行嗎?

其實(shí)并不是這樣的

notify_one()

喚醒wait()函數(shù),當(dāng)前所再的線程嘗試獲得鎖

某個線程執(zhí)行完notify_one函數(shù)后,會返回到另一個線程中的wait函數(shù)處,并將其"喚醒",讓其繼續(xù)執(zhí)行,自己的線程和wait線程都嘗試獲得鎖來進(jìn)行下一步執(zhí)行

不是順序執(zhí)行的解釋

  • 當(dāng)wait函數(shù)后面有很多語句要執(zhí)行,但是再此之前wait所在的線程函數(shù)中就已經(jīng)將鎖進(jìn)行釋放了,那么notify_one的“喚醒”就不在生效,兩個線程都嘗試獲得鎖,但是wait所在的線程有很多語句要執(zhí)行,耗時高,那么很有可能notify_one所在的線程就再次獲得了鎖,進(jìn)行下一步操作。
  • 這樣就不一定是順序執(zhí)行的宏觀表現(xiàn)了
#include<iostream>
#include<mutex>
#include<list>
#include<thread>
using namespace std;
class Obj
{
private:
	list<int> myList;
	condition_variable var;
	mutex tex;
public:
	bool popFromList(int & comb)
	{
		if (!myList.empty()) {
			unique_lock<mutex> cur(tex);
			if (!myList.empty())
			{
				comb = myList.front();
				myList.pop_front();
				return true;
			}
		}
		return false;
	}
	void inToList()
	{
		for (int i = 0; i < 1000; i++)
		{
			cout << this_thread::get_id() << "正在向list中添加數(shù)據(jù)>; " << i << endl;
			unique_lock<mutex> cur(tex);
			myList.push_back(i);
			var.notify_one();
		}
	}
	void outFromList()
	{
		while(true)
		{
			unique_lock<mutex> cur(tex);
			var.wait(cur, [this] {
				if (!myList.empty())
					return true;
				return false;
				});
			int comb = myList.front();
			myList.pop_front();
			cur.unlock();
			cout << this_thread::get_id() << "正在取出數(shù)據(jù)>: " << comb << endl;
			chrono::seconds tim(2);
			this_thread::sleep_for(tim);
			cout <<this_thread::get_id() <<  "睡眠兩秒后執(zhí)行" << endl;
		}
	}
};
int main()
{
	Obj obj;
	thread thread1(&Obj::outFromList, &obj);
	thread thread2(&Obj::inToList, &obj);
	thread1.join();
	thread2.join();
	cout << "這里是主線程" << endl;
}

如圖所示,在notify_one線程執(zhí)行835次循環(huán)后,wait所在的線程才獲得了鎖,繼續(xù)執(zhí)行

在此之前的所有notify_one的喚醒操作都是無效的。

然后在notify_one線程執(zhí)行完畢之后,wait再次獲得了鎖,繼續(xù)向下執(zhí)行

notify_all()

顧名思義,是“喚醒”所有的wait函數(shù)線程,但是并不是都一起運(yùn)行,因?yàn)樗麄円M(jìn)行鎖的請求,僅僅只能由一把鎖存在,只有獲得鎖并且lambda表達(dá)式返回結(jié)果為true的線程才能繼續(xù)執(zhí)行

到此這篇關(guān)于C++在多線程中使用condition_variable實(shí)現(xiàn)wait的文章就介紹到這了,更多相關(guān)C++ condition_variable內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • QT使用udp實(shí)現(xiàn)發(fā)送與接收圖片

    QT使用udp實(shí)現(xiàn)發(fā)送與接收圖片

    這篇文章主要為大家詳細(xì)介紹了QT如何使用udp協(xié)議實(shí)現(xiàn)發(fā)送與接收圖片功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • C++17新特性個人總結(jié)

    C++17新特性個人總結(jié)

    這篇文章主要介紹了C++17新特性個人總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 最小生成樹算法C語言代碼實(shí)例

    最小生成樹算法C語言代碼實(shí)例

    這篇文章主要介紹了最小生成樹算法C語言代碼實(shí)例,有需要的朋友可以參考一下
    2013-12-12
  • C語言隨機(jī)數(shù)生成教程(rand和srand用法)

    C語言隨機(jī)數(shù)生成教程(rand和srand用法)

    這篇文章主要介紹了C語言隨機(jī)數(shù)生成教程(rand和srand用法),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Qt 實(shí)現(xiàn)桌面雪花飄落代碼

    Qt 實(shí)現(xiàn)桌面雪花飄落代碼

    這篇文章主要介紹了Qt實(shí)現(xiàn)桌面雪花飄落代碼,有需要的朋友可以參考一下
    2013-12-12
  • C++超詳細(xì)講解逗號操作符

    C++超詳細(xì)講解逗號操作符

    使用逗號運(yùn)算符是為了把幾個表達(dá)式放在一起。整個逗號表達(dá)式的值為系列中最后一個表達(dá)式的值。從本質(zhì)上講,逗號的作用是將一系列運(yùn)算按順序執(zhí)行
    2022-05-05
  • C++音樂播放按鈕的封裝過程詳解

    C++音樂播放按鈕的封裝過程詳解

    此篇文章用于記錄學(xué)習(xí)C++封裝音樂播放按鈕,封裝將對象的屬性和行為作為一個整體,表現(xiàn)生活中的事物、將屬性和行為加以權(quán)限控制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 使用C/C++語言生成一個隨機(jī)迷宮游戲

    使用C/C++語言生成一個隨機(jī)迷宮游戲

    迷宮相信大家都走過,主要是考驗(yàn)?zāi)愕倪壿嬎季S。今天小編使用C語言生成一個隨機(jī)迷宮游戲,具體實(shí)現(xiàn)代碼,大家通過本文學(xué)習(xí)吧
    2016-12-12
  • C++與C語言常用的語法對比

    C++與C語言常用的語法對比

    這篇文章主要介紹了C++與C語言常用的語法對比,文章基于c++和C語言的相關(guān)資料展開兩者的語法相互對比,需要的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助
    2022-04-04
  • VC++中HTControl的CHTButton按鈕控件類用法實(shí)例解析

    VC++中HTControl的CHTButton按鈕控件類用法實(shí)例解析

    這篇文章主要介紹了VC++中HTControl的CHTButton按鈕控件類用法,對于大家進(jìn)行VC++項目開發(fā)有一定的幫助作用,需要的朋友可以參考下
    2014-08-08

最新評論

施甸县| 琼结县| 长阳| 若尔盖县| 南投县| 南投县| 湛江市| 芮城县| 满城县| 崇阳县| 湖口县| 吕梁市| 东明县| 连南| 桦川县| 花莲市| 平昌县| 兴化市| 衡阳市| 浦北县| 思茅市| 栾川县| 海林市| 潍坊市| 黄浦区| 北海市| 北碚区| 小金县| 舟山市| 安宁市| 出国| 曲水县| 清原| 会东县| 应用必备| 留坝县| 溆浦县| 合肥市| 日土县| 永城市| 金昌市|