欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

有這樣的需求

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

wait()

  • 可以接受兩個參數(shù),其中第一個參數(shù)是鎖對象,第二個參數(shù)是lambda表達式,其中的lambda表達式的返回值要是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表達式

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

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

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

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

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

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

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

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

其實并不是這樣的

notify_one()

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

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

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

  • 當wait函數(shù)后面有很多語句要執(zhí)行,但是再此之前wait所在的線程函數(shù)中就已經(jīng)將鎖進行釋放了,那么notify_one的“喚醒”就不在生效,兩個線程都嘗試獲得鎖,但是wait所在的線程有很多語句要執(zhí)行,耗時高,那么很有可能notify_one所在的線程就再次獲得了鎖,進行下一步操作。
  • 這樣就不一定是順序執(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ù)線程,但是并不是都一起運行,因為他們要進行鎖的請求,僅僅只能由一把鎖存在,只有獲得鎖并且lambda表達式返回結果為true的線程才能繼續(xù)執(zhí)行

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

相關文章

  • C++中測試程序運行時間的幾種方法總結

    C++中測試程序運行時間的幾種方法總結

    本文介紹了C++中測量程序運行時間的幾種方法,包括使用GetTickCount()、clock()、Boost庫的timer類以及高精度時控函數(shù)QueryPerformanceFrequency和QueryPerformanceCounter,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-09-09
  • 簡單分析針對ARM平臺的C語言程序的編譯問題

    簡單分析針對ARM平臺的C語言程序的編譯問題

    這篇文章主要介紹了針對ARM平臺的C語言程序的編譯問題,從優(yōu)化編譯選項的幾個方面進行分析,需要的朋友可以參考下
    2015-12-12
  • Windows安裝Qt6.4.2及簡單驗證

    Windows安裝Qt6.4.2及簡單驗證

    本文主要介紹了Windows安裝Qt6.4.2及簡單驗證,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • C語言超詳細講解指針的概念與使用

    C語言超詳細講解指針的概念與使用

    本文主要講解C語言中指針和字符串的關系以及指針和數(shù)組的關系,在看本文之前大家可以先看看博主之前的C語言基礎篇,先對C語言指針先有個基礎的了解,有助于對本文章有更深一步的了解
    2022-05-05
  • C++實現(xiàn)經(jīng)典24點紙牌益智游戲

    C++實現(xiàn)經(jīng)典24點紙牌益智游戲

    這篇文章主要介紹了C++實現(xiàn)經(jīng)典24點紙牌益智游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C語言數(shù)據(jù)結構與算法時間空間復雜度基礎實踐

    C語言數(shù)據(jù)結構與算法時間空間復雜度基礎實踐

    這篇文章主要為大家介紹了C語言數(shù)據(jù)結構與算法中時間空間復雜度的基礎實踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-02-02
  • 深入內存對齊的詳解

    深入內存對齊的詳解

    本篇文章是對內存對齊進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++反射的一種實現(xiàn)方法詳解

    C++反射的一種實現(xiàn)方法詳解

    這篇文章主要給大家介紹了關于C++反射的一種實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用C++具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-06-06
  • Qt中QSettings配置文件的讀寫和應用場景詳解

    Qt中QSettings配置文件的讀寫和應用場景詳解

    這篇文章主要給大家介紹了關于Qt中QSettings配置文件的讀寫和應用場景的相關資料,QSettings能讀寫配置文件,當配置文件不存在時,可生成配置文件,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-10-10
  • dword ptr指令詳細解析

    dword ptr指令詳細解析

    8086CPU的指令,可以處理兩種尺寸的數(shù)據(jù),byte和word。所以在機器指令中要指明,指令進行的是字操作還是字節(jié)操作
    2013-09-09

最新評論