C++11 多線程學習----std::thread類的簡單使用

一 C++11多線程簡介

    C++11標準庫會提供類threadstd::thread)。若要運行一個線程,可以創建一個類thread的實體,其初始參數爲一個函數對象,以及該函數對象所需要的參數。通過成員函數std::thread::join()對線程會合的支持,一個線程可以暫停直到其它線程運行完畢。若有底層平臺支持,成員函數std::thread::native_handle()將可提供對原生線程對象運行平臺特定的操作。對於線程間的同步,標準庫將會提供適當的互斥鎖(像是std::mutexstd::recursive_mutex等等)和條件參數(std::condition_variablestd::condition_variable_any)。前述同步機制將會以RAII鎖(std::lock_guardstd::unique_lock)和鎖相關算法的方式呈現,以方便程序員使用。

對於要求高性能,或是極底層的工作,有時或甚至是必須的,我們希望線程間的通信能避免互斥鎖使用上的開銷。以原子操作來訪問內存可以達成此目的。針對不同情況,我們可以通過顯性的內存屏障改變該訪問內存動作的可見性。

對於線程間異步的傳輸,C++11標準庫加入了以及std::packaged_task用來包裝一個會傳回異步結果的函數調用。因爲缺少結合數個future的功能,和無法判定一組promise集合中的某一個promise是否完成,futures此一提案因此而受到了批評。

更高級的線程支持,如線程池,已經決定留待在未來的TechnicalReport加入此類支持。更高級的線程支持不會是C++11的一部分,但設想是其最終實現將創建在目前已有的線程支持之上。

     std::async提供了一個簡便方法以用來運行線程,並將線程綁定在std::future。用戶可以選擇一個工作是要多個線程上異步的運行,或是在一個線程上運行並等待其所需要的數據。默認的情況,實現可以根據底層硬件選擇前面兩個選項的其中之一。另外在較簡單的使用情形下,實現也可以利用線程池提供支持。

 

二 簡單std::thread的使用

        

#include <iostream>
#include <thread>
 
using namespace std;
 
void myFirstThread()
{
         cout << "Hello thread" << endl;
}
 
int main()
{
         thread myThread(myFirstThread);
         myThread.join();
         return 0;
}


三 std::thread類構造函數函數簡介

  

std::thread構造

1 默認構造,創建一個空的thread對象,以下爲默認構造函數聲明:

thread() noexcept;

2拷貝構造 copy-delete(thread對象不可拷貝構造)

thread (const thread&) = delete;

3初始化構造,創建thread對象,該對象可被joinable,線程會調用fn函數,參數由args給出,下邊爲初始化構造   函數聲明:

template <class Fn, class... Args>

explicit thread (Fn&& fn,Args&&... args);

4移動構造 move此構造函數調用成功之後,x不代表任何thread可執行對象。

thread (thread&& x) noexcept;

注意:可被joinable的thread對象必須在他們銷燬之前被主線程join或者將之設置爲detached。
 
std::thread各種構造函數示例如下:
#include <iostream>
#include <thread>

using namespace std;

void myFirstThreadTask(int num)
{
	for (int i = 0; i < 10; ++i)
	{
		cout << "myFirstThreadTask's num = " << num++ << endl;
		this_thread::sleep_for(chrono::milliseconds(10));
	}
}

void mySecondThreadTask(int &num)
{
	for (int i = 0; i < 10; ++i)
	{
		cout << "mySecondThreadTask's num = " << num++ << endl;
		this_thread::sleep_for(std::chrono::milliseconds(10));
	}
}

int main(int argc, _TCHAR* argv[])
{
	int n = 5;
	thread myThread0;//myThread1爲一個空線程,不代表任何可執行對象

	//myThread1與myFirstThreadTask函數綁定,n爲其按值傳遞參數
	thread myThread1(myFirstThreadTask,n);

	//myThread2與mySecondThreadTask函數綁定,n爲其引用傳遞參數
	thread myThread2(mySecondThreadTask,std::ref(n));

	//現在myThread2不代表任何可執行對象,myThread3與mySecondThreadTask函數綁定
	thread myThread3(std::move(myThread2));

	myThread1.join();
	myThread3.join();


	
	//myThread3.join();
	return 0;
}





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