C++11併發程式設計:多執行緒std::thread

蝸牛201發表於2018-12-20

一:概述

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程式設計等相關技術,還有高薪網際網路職位內推,在這裡一起探討,一起學習,一起進步,同時不定期分享視訊書籍資源,充分利用碎片化時間,讓我們的技術之路更加有樂趣!

相關文章