C++11並發編程:多線程std::thread


一:概述

C++11引入了thread類,大大降低了多線程使用的復雜度,原先使用多線程只能用系統的API,無法解決跨平台問題,一套代碼平台移植,對應多線程代碼也必須要修改。現在在C++11中只需使用語言層面的thread可以解決這個問題。

所需頭文件<thread>

二:構造函數

1.默認構造函數

thread() noexcept
一個空的std::thread執行對象

2.初始化構造函數

template<class Fn, class... Args>
explicit thread(Fn&& fn, Args&&... args);
創建std::thread執行對象,線程調用threadFun函數,函數參數為args。

1 void threadFun(int a)
2 {
3     cout << "this is thread fun !" << endl;
4 }
5 
6 thread t1(threadFun, 2);

3.拷貝構造函數

thread(const thread&) = delete;
拷貝構造函數被禁用,std::thread對象不可拷貝構造

1 void threadFun(int& a)
2 {
3     cout << "this is thread fun !" << endl;
4 }
5     
6 int value = 2;
7 thread t1(threadFun, std::ref(value));

4.Move構造函數

thread(thread&& x)noexcept
調用成功原來x不再是std::thread對象

1 void threadFun(int& a)
2 {
3     cout << "this is thread fun !" << endl;
4 }
5 
6 int value = 2;
7 thread t1(threadFun, std::ref(value));
8 thread t2(std::move(t1));
9 t2.join();

三:成員函數

1.get_id()

獲取線程ID,返回類型std::thread::id對象。

 1 thread t1(threadFun);
 2 thread::id threadId = t1.get_id();
 3 cout << "線程ID:" << threadId << endl;
 4 
 5 //threadId轉換成整形值,所需頭文件<sstream>
 6 ostringstream   oss;
 7 oss << t1.get_id();
 8 string strId = oss.str();
 9 unsigned long long tid = stoull(strId);
10 cout << "線程ID:" << tid << endl;

2.join()

創建線程執行線程函數,調用該函數會阻塞當前線程,直到線程執行完join才返回。

thread t1(threadFun);
t1.join()  //阻塞等待

3.detach()

detach調用之后,目標線程就成為了守護線程,駐留后台運行,與之關聯的std::thread對象失去對目標線程的關聯,無法再通過std::thread對象取得該線程的控制權。

4.swap()

交換兩個線程對象

1 thread t1(threadFun1);
2 thread t2(threadFun2);
3 cout << "線程1的ID:" << t1.get_id() << endl;
4 cout << "線程2的ID:" << t2.get_id() << endl;
5 
6 t1.swap(t2);
7 
8 cout << "線程1的ID:" << t1.get_id() << endl;
9 cout << "線程2的ID:" << t2.get_id() << endl;

5.hardware_concurrency()

獲得邏輯處理器儲量,返回值為int型

 1 int coreNum = thread::hardware_concurrency(); 

四:使用

 1.創建線程

 1 void threadFun1()
 2 {
 3     cout << "this is thread fun1 !" << endl;
 4 }
 5 
 6 int main()
 7 {
 8     thread t1(threadFun1);
 9     t1.join();
10 
11     getchar();
12     return 1;
13 }

2.創建線程,傳參

 1 void threadFun1(int v)
 2 {
 3     cout << "this is thread fun1 !" << endl;
 4     cout << v << endl;
 5 }
 6 
 7 int main()
 8 {
 9     int value = 6;
10     thread t1(threadFun1, value);
11     t1.join();
12 
13     getchar();
14     return 1;
15 }

需要注意,變量int value 和int v 做變量傳遞時並不是引用,而是對變量做了拷貝,所以在傳遞給int v前,int value不能出作用域(釋放了內存),join(),可以保證int value變量釋放內存,如果使用detach(),可能存在這種情況。

3.創建線程,引用傳參

 1 void threadFun1(int& v)
 2 {
 3     cout << "this is thread fun1 !" << endl;
 4     cout << v << endl;
 5 }
 6 
 7 int main()
 8 {
 9     int value = 6;
10     thread t1(threadFun1, std::ref(value));
11     t1.join();
12 
13     getchar();
14     return 1;
15 }

4.創建建線程,線程函數為類成員函數

 1 class Object
 2 {
 3 public:
 4     Object()
 5     {
 6         cout << "構造函數" << endl;
 7     }
 8 
 9     ~Object()
10     {
11         cout << "析構函數" << endl;
12     }
13 
14     void fun(string info)
15     {
16         cout << info << endl;
17     }
18 
19 };
20 
21 int main()
22 {
23 
24     Object obj;
25     string str = "我是一個類的成員函數!";
26     thread t1(&Object::fun, &obj, str);
27     t1.join();
28 
29     getchar();
30     return 1;
31 }

 

掃碼關注公眾號

專注分享C/C++,C++(11,14,17),STL,Java,Spring,mybatis,mysql,redis,分布式,高並發,設計模式,爬蟲,docker,shell編程等相關技術,還有高薪互聯網職位內推,在這里一起探討,一起學習,一起進步,同時不定期分享視頻書籍資源,充分利用碎片化時間,讓我們的技術之路更加有樂趣!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM