程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++11 多線程學習

C++11 多線程學習

編輯:關於C++

一 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 
#include 
 
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

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

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

thread (thread&& x) noexcept;

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

 

#include 
#include 

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 _tmain(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));
	myThread1.join();
	myThread2.join();

	n++;

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


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved