【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 }

 

 

 
posted @ 2020-06-06 11:29  Chen沉尘  阅读(5815)  评论(0编辑  收藏  举报