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

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

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

前言

有這樣的需求

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

wait()

  • 可以接受兩個(gè)參數(shù),其中第一個(gè)參數(shù)是鎖對象,第二個(gè)參數(shù)是lambda表達(dá)式,其中的lambda表達(dá)式的返回值要是bool類型
  • 也可接受一個(gè)參數(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ù)時(shí),會(huì)執(zhí)行l(wèi)ambda表達(dá)式

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

返回值為true時(shí)就嘗試獲得鎖

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

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

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

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

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

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

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

notify_one()

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

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

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

  • 當(dāng)wait函數(shù)后面有很多語句要執(zhí)行,但是再此之前wait所在的線程函數(shù)中就已經(jīng)將鎖進(jìn)行釋放了,那么notify_one的“喚醒”就不在生效,兩個(gè)線程都嘗試獲得鎖,但是wait所在的線程有很多語句要執(zhí)行,耗時(shí)高,那么很有可能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新特性個(gè)人總結(jié)

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

    這篇文章主要介紹了C++17新特性個(gè)人總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(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í)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Qt 實(shí)現(xiàn)桌面雪花飄落代碼

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

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

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

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

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

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

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

    迷宮相信大家都走過,主要是考驗(yàn)?zāi)愕倪壿嬎季S。今天小編使用C語言生成一個(gè)隨機(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++項(xiàng)目開發(fā)有一定的幫助作用,需要的朋友可以參考下
    2014-08-08

最新評(píng)論

武穴市| 宜都市| 武定县| 行唐县| 萍乡市| 太和县| 东山县| 长岭县| 贵南县| 运城市| 福贡县| 民权县| 珠海市| 法库县| 临夏县| 荃湾区| 长阳| 乌兰浩特市| 建平县| 贡山| 霍城县| 新竹市| 铜鼓县| 呼图壁县| 惠水县| 武平县| 库车县| 定西市| 旬邑县| 珲春市| 东安县| 五峰| 喀喇沁旗| 会东县| 津南区| 武宁县| 九寨沟县| 佳木斯市| 龙海市| 上思县| 永吉县|