C++併發與多線程 condition_variable、wait、notify_one、notify_all使用方法

條件變量condition_variable

假設有兩個線程,一個線程A一個線程B。
線程A:等待一個條件滿足.
線程B:專門往消息隊列中扔消息(數據)
condition_variable是一個類,和條件相關的類,等待一個條件完成,需要和互斥量配合工作,用的時候需要生成這個類的對象。

condition_variable成員函數wait

在這裏插入圖片描述
第一個參數是一個鎖,第二個參數是一個可調用對象。
如果第二個參數返回true,wait()直接返回。
如果第二個參數返回false,那麼wati()將解鎖互斥量,並堵塞直到其他某個線程調用notify_one()成員函數爲止。
如果wait()沒有第二個參數,那麼就和第二個參數返回false的效果一樣。

wait喚醒後,wait將幹以下工作:
1.不斷嘗試重新獲取互斥量鎖,如果獲取不到,流程就卡在wait這裏等着獲取,如果獲取獲取到了就繼續執行2
2.獲取到了鎖然後上鎖,如果wait有第二個參數,就判斷第二個參數,如果第二個參數返回false,那wait又解鎖互斥量,並堵塞直到其他某個線程調用notify_one()成員函數爲止。
3.如果第二個參數返回true,則wait返回,流程走下去。
4.如果沒有第二個參數,wait返回,流程走下去。

condition_variable成員函數notify_one

其他線程調用notify_one()將wait的狀態喚醒後,wait恢復工作。
如果wait並沒有堵塞,那麼此時notify_one調用可能就沒有效果.

使用例子

class A
{
private:
	list<int>msgqueue;
	mutex mymutex1;
	condition_variable mycon;//生成一個條件變量對象
public:
	void MsgEnqueue()
	{
		int commmand = 0;
		while (true)
		{
			unique_lock<mutex>l(mymutex1);
			mycon.wait(l, [this] 
			{
				if (!msgqueue.empty())
					return true;
				return false;
			});
			commmand = msgqueue.front();
			msgqueue.pop_front();
			l.unlock();//隨時unlock()
			cout << "MsgEnqueue執行,取出一個元素 " << commmand << endl;

		}

		return;
	}
	void MsgDequeue()
	{

		for (int i = 0; i < 10000; ++i)
		{
			cout << "MsgDequeue執行,插入一個元素" << i << endl;
			unique_lock<mutex>l(mymutex1);
			msgqueue.push_back(i);
			mycon.notify_one();//嘗試把wait()線程喚醒
		}

	}
};
int main()
{
	A a;
	thread t1(&A::MsgEnqueue, &a);
	thread t2(&A::MsgDequeue, &a);
	t1.join();
	t2.join();
	cout << endl;
}

在這裏插入圖片描述

condition_variable成員函數notify_all

喚醒所有wait()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章