【C++多線程】創建啟動線程及查看線程id


創建線程

  子線程在創建時啟動。使用功能std::thread類創建線程對象。

  線程關聯的可調對象可以是:普通函數、仿函數對象、Lambda表達式、非靜態成員函數、靜態成員函數

示例

  普通函數

 1 #include <thread>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 void test()
 7 {
 8     cout << "子線程開始執行!" << endl;
 9     //do something
10     cout << "子線程執行完畢!" << endl;
11 }
12 int main()
13 {
14     thread t(test);
15     t.join();   //主線程等待子線程
16     return 0;
17 }

  仿函數對象

 1 #include <thread>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 class Test{
 6 public:
 7     void operator()(){
 8         cout << "子線程開始執行!" << endl;
 9         //do something
10         cout << "子線程執行完畢!" << endl;
11     }
12     
13 };
14 int main()
15 {
16     // thread t(Test()); 這種寫法會編譯器會認為是一個函數聲明,這個函數帶有一個參數(函數指針指向沒有參數並返回Test對象的函數)
17     thread t((Test()));  //可以使用加小括號,或者使用一只初始化,或者傳入命名變量
18     t.join();   //主線程等待子線程
19     return 0;
20 }

  Lambda表達式

 1 #include <thread>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     thread t(
 9         [] () {
10             cout << "子線程開始執行!" << endl;
11             //do something
12             cout << "子線程執行完畢!" << endl;  
13         }
14         );
15     t.join();   //主線程等待子線程
16     return 0;
17 }

  非靜態成員函數,靜態成員函數

  以下的下寫法中是將對象拷貝了一份副本來創建線程。當我們在進行共享數據的管理時,有時候需要傳入對象的指針或者地址。而靜態成員函數,不需要傳入對象,只需要傳入類函數地址。根據C++對象模型,這很好理解因為編譯器對非靜態成員函數的處理需要this指針,而對靜態成員函數的處理不需要。【C++】對象模型之Function

 

 1 #include <thread>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 class Test{
 6 public:
 7     void test(){
 8         cout << "子線程開始執行!" << endl;
 9         // do somesthing
10         cout << "子線程執行完畢!" << endl;
11     }
12 };
13 
14 int main()
15 {
16     Test obj;
17     thread t(&Test::test, obj); //注意寫法,傳入成員函數地址,還需要傳入對象
18     t.join();   //主線程等待子線程
19     return 0;
20 }

容器管理多個線程

  我們可以使用容器來對多個線程進程管理,為自動化管理線程打下基礎。另外std::thread::hardware_concurrency()返回硬件支持並發的線程數量,這里的並發是指硬件可以並行執行多少個線程,而不是我們一般所說的時間片輪轉的那種並發。例如,多核系統中,返回值可以是CPU核芯的數量。

 1 #include <iostream>
 2 #include <thread>
 3 #include <vector>
 4 
 5 using namespace std;
 6 
 7 void func(int i)
 8 {
 9     cout << "子線程func" << i << "開始執行!" << endl;
10     //do something
11     //方法二
12     cout << "func線程" << i << "的id: " << this_thread::get_id() << endl;
13     cout << "子線程func" << i << "執行結束!" << endl;
14 }
15 
16 int main()
17 {
18     cout << "主線程main開始執行!" << endl;
19     cout <<  "main線程的id: " << this_thread::get_id() << endl;
20     vector<thread> thdvec;
21     int n;
22     cin >> n;
23     //運行時確定線程數量
24     for (int i = 0; i < n; ++i)
25         thdvec.push_back(thread(func, i));
26 
27     for (auto iter = thdvec.begin(); iter != thdvec.end(); ++iter)
28         iter->join();
29     cout << "主線程main執行結束!" << endl;
30     return 0;
31 }

 

 

獲取線程id

  線程標識類型是 std::thread::id 類型。有兩種獲取id的方法。

  方法一:可以通過調用 std::thread 對象的成員函數 get_id() 來獲取id。

 

  方法二:在當前線程中使用std::this_thread::get_id()來獲取線程id。

 

 1 #include <thread>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 void func()
 7 {
 8     cout << "子線程func開始執行!" << endl;
 9     //do something
10     //方法二
11     cout << "func線程的id: " << this_thread::get_id() << endl;
12     cout << "子線程func執行結束!" << endl;
13 }
14 
15 int main()
16 {
17 
18     cout << "主線程main開始執行!" << endl;
19     cout <<  "main線程的id: " << this_thread::get_id() << endl;
20     thread t(func);
21     //方法一
22     cout << "在main線程中獲取func線程id:" << t.get_id() << endl;
23     t.join(); 
24     cout << "主線程main執行結束!" << endl;
25     return 0;
26 }

 

 

 


免責聲明!

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



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