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

     
  • 相关阅读:
    Javascript高级编程学习笔记(32)—— 客户端检测(1)能力检测
    Javascript高级编程学习笔记(31)—— BOM(5)screen、history对象
    Javascript高级编程学习笔记(30)—— BOM(4)navigator对象
    Javascript高级编程学习笔记(29)—— BOM(3)location对象
    Javascript高级编程学习笔记(28)—— BOM(2)window对象2
    Javascript高级编程学习笔记(27)—— BOM(1)window对象1
    逆向与反汇编工具
    Silicon Labs
    sk_buff 里的len, data_len, skb_headlen
    IP分片重组的分析和常见碎片攻击 v0.2
  • 原文地址:https://www.cnblogs.com/chen-cs/p/13054027.html
Copyright © 2020-2023  润新知