1. 程式人生 > >c++11中condition_variable訊號量的標準用法。

c++11中condition_variable訊號量的標準用法。

目標:主執行緒向其它執行緒發生訊息,其它執行緒收到訊息並處理。

虛擬碼目標:主執行緒將訊息加入listTemp連結串列,使用condition_variable的notify_one通知執行緒,其它執行緒將訊息處理,並將訊息加入到已處理listTemp2連結串列中。

 虛擬碼

#include <atomic>
#include <mutex>
#include <list>
#include <vector>
#include <thread>
#include <cassert>


int main()
{
	std::atomic<int> nNum = ATOMIC_VAR_INIT(0);

	std::mutex listMu;
	std::list<int> listTemp;

	std::mutex listMu2;
	std::list<int> listTemp2;

	std::condition_variable listCondition;

	std::vector<std::shared_ptr < std::thread >> listThread;

	int const nMax = 1000;

	for (int i = 0; i != 10; ++i)
	{
		auto pTh = std::make_shared <std::thread>([&listTemp,&listCondition,&listMu,&nNum,&listTemp2,&listMu2,nMax]
			()->void
		{
			
			while (true)
			{		
				int i = -1;

				{
					std::unique_lock<std::mutex> lc(listMu);
					while (listTemp.empty())
					{
						listCondition.wait(lc);

						{
							std::lock_guard<std::mutex> lc(listMu2);
							if (listTemp2.size() == nMax)
							{
								break;
							}
						}
					}

					{
						std::lock_guard<std::mutex> lc(listMu2);
						if (listTemp2.size() == nMax)
						{
							listCondition.notify_one();
							break;
						}
					}


					i = *listTemp.begin();
					listTemp.erase(listTemp.begin());					
				}
			



				//處理比較耗時的操作


				{
					std::lock_guard<std::mutex> lc(listMu2);
					listTemp2.push_back(i);
					if (listTemp2.size() == nMax)
					{
						listCondition.notify_one();
						break;
					}
				}

				std::this_thread::sleep_for(std::chrono::milliseconds(100));

				

			}
			
		});

		listThread.push_back(pTh);
	}	
		
	for (int i = 0; i != nMax; ++i)
	{
		{
			std::lock_guard<std::mutex> lc(listMu);
			listTemp.push_back(i);
			listCondition.notify_one();
		}		
		std::this_thread::sleep_for(std::chrono::milliseconds(15));
	}		

	//listCondition.notify_all();
	for (auto t : listThread)
	{
		t->join();
	}

	assert(nMax == listTemp2);

	std::cout << "結束" << std::endl;

	getchar();
    return 0;
}

程式碼保證訊息不會有遺漏,並且所有訊息都能得到處理。但是並不保證,已處理的訊息連結串列中的順序與加入訊息的順序一致。

相關推薦

c++11condition_variable訊號標準用法

目標:主執行緒向其它執行緒發生訊息,其它執行緒收到訊息並處理。 虛擬碼目標:主執行緒將訊息加入listTemp連結串列,使用condition_variable的notify_one通知執行緒,其它執行緒將訊息處理,並將訊息加入到已處理listTemp2連結串列中。  虛擬

c++11訊號例項

      C++11的新特性中,一些封裝的庫使得開發人員更加方便,比如thread,mutex等這些都是Linux常用的庫,而關於semaphore訊號量相關的封裝,卻沒有做到。然而我們可以利用互

C++11vector的emplace_back用法及輸入輸出操作符的過載

#include <vector> #include <iostream> #include <string> using namespace std; struc

C++11 std::function和std::bind的用法

關於std::function 的用法: 其實就可以理解成函式指標 1. 儲存自由函式 void printA(int a) { cout<<a<<endl; } std::function<void(int a)

c++11enum class的用法詳解

要了解enum class的出現,則需要首先了解enum,方才知道為何有這東西。那麼Meyers首先舉出一個例子來闡述: enum Color {black, white, red}; auto white = false; // error 其緣由在於black, white, red等並沒有屬於C

c++ 11emplace_back替代push_back的相關知識點,含右值引用,move用法

C++11引入了右值引用,轉移建構函式,push_back()右值時就會呼叫建構函式和轉移建構函式(原來是呼叫拷貝構造,會為臨時變數申請堆空間,影響程式效率,C++11以後為右值引用呼叫轉移建構函式,不會為臨時變數申請堆空間,而是直接賦值,提高程式效率)。 使用mplace_back替代push_back()

執行緒與互斥鎖(C++11std::thread和std::mutex的用法

執行緒 0 首先是曾經在MultiCMOS專案中用到的: #include <thread> //包含標頭檔案 class IDataProcessUnit { protected:

C++11function物件作回撥函式的用法

Thread中的函式回撥方法,儲存著以後使用。 #ifndef THREAD_H_ #define THREAD_H_ #include <boost/noncopyable.hpp>

STL/Boost C++ 11 foreach的用法

本篇將對C++ 標準庫中的兩種foreach,以及boost中的BOOST_FOREACH進行講解說明 #include <iostream> #include <algorithm> #include <string> #include

C++11 的function和bind、lambda用法

get foo 隱式轉換 function for_each sstream ios 無法 href std::function 1. std::bind綁定一個成員函數 1 #include <iostream> 2 #include

C++11智能指針的原理、使用、實現

his animal something include expire another .cn 表現 oid 目錄 理解智能指針的原理 智能指針的使用 智能指針的設計和實現 1.智能指針的作用 C++程序設計中使用堆內存是非

C++11多線程庫

標準 value 生命周期 通過 死鎖 strong () 四種 ... 一、linux 線程同步 線程是在操作系統層面支持的,所以多線程的學習建議還是先找一本linux系統編程類的書,了解linux提供多線程的API。完全完全使用系統調用編寫多線程程序是痛苦,現

C++11對容器的各種循環遍歷的效率比較

ets normal pre unsigned int qdebug tex contain string 1 #include "CycleTimeTst.h" 2 #include <string> 3 #include <vector&

C++11lock_guard和unique_lock的區別

target san color member uri display each for clas c++11中有一個區域鎖lock_guard,還有第二個區域鎖unique_lock。 區域鎖lock_guard使用起來比較簡單,除了構造函數外沒有其他member fu

HTML頁面固定變用法

index.php title 開始 中一 src .com 表示 init bsp <a href="index.php?m=search&c=index&a=init&typeid=&siteid=1&q={$title}

C++11 實現信號Semaphore類

signed clas 可能 details 時有 art one http spa 1 #pragma once 2 #include <mutex> 3 #include <condition_variable> 4 class Sem

c++for的四種用法

四種 mes pre using In col space c++ names #include <algorithm> #include <vector> #include <iostream> using namespace

C++11的技術剖析( std bind原理簡單圖解)

簡化 靜態成員函數 div 語法 con mar clear 函數 多余 此文為轉載,好像原出處的原文已經無法打開了。 本文解釋了bind 是如何工作的。為了清晰,我對圖中的語法作了一些簡化(例如,省略函數調用操作符的參數類型),並且簡化了 bind 的實現. bin

C++11如何輸出enum class的值

gic log its may aps cti return cout cast Unlike an unscoped enumeration, a scoped enumeration is not implicitly convertible to its intege

c++類public,private,protected的用法與區別

1、public修飾的成員變數 在程式的任何地方都可以被訪問,就是公共變數的意思,不需要通過成員函式就可以由類的例項直接訪問 2、private修飾的成員變數 只有類內可直接訪問,私有的,類的例項要通過成員函式才可以訪問,這個可以起到資訊隱藏 3、protected是受保護變數 類內