• C++11 thread


    目录

    线程thread

    主要成员函数

    简单线程的创建 

    线程封装 

    zero_thread.h

    zero_thread.cpp

    main.cpp


    C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂

    线程thread

    std::thread 在 #include 头文件中声明,因此使用 std::thread 时需要包含 #include 头文件。

    #include // 头文件

    std::thread(...)

    主要成员函数

    get_id()
    获取线程ID,返回类型std::thread::id对象。
    http://www.cplusplus.com/reference/thread/thread/get_id/


    joinable()
    判断线程是否可以加入等待
    http://www.cplusplus.com/reference/thread/thread/joinable/


    join()
    等该线程执行完成后才返回。
    http://www.cplusplus.com/reference/thread/thread/join/


    detach()

            detach调用之后,目标线程就成为了守护线程,驻留后台运行,与之关联的std::thread对象失去对目标线程的关联,无法再通过std::thread对象取得该线程的控制权。当线程主函数执行完之后,线程就结束了,运行时库负责清理与该线程相关的资源。

            调用 detach 函数之后:
            *this 不再代表任何的线程执行实例。
            joinable() == false
            get_id() == std::thread::id()
    http://www.cplusplus.com/reference/thread/thread/detach/

    简单线程的创建 

    1. 1. 传入0个值
    2. 2. 传入2个值
    3. 3. 传入引用
    4. 4. 传入类函数
    5. 5. detach
    6. 6. move
    1. #include <iostream>
    2. #include <thread>
    3. using namespace std;
    4. // 1 传入0个值
    5. void func1()
    6. {
    7. cout << "func1 into" << endl;
    8. }
    9. // 2 传入2个值
    10. void func2(int a, int b)
    11. {
    12. cout << "func2 a + b = " << a + b << endl;
    13. }
    14. void func2_1(int a, int b)
    15. {
    16. cout << "func2_1 a + b = " << a + b << endl;
    17. }
    18. int func2_1(string a, string b)
    19. {
    20. cout << "func2_1 a + b = " << a << b << endl;
    21. return 0;
    22. }
    23. // 3 传入引用
    24. void func3(int& c) // 引用传递
    25. {
    26. cout << "func3 c = " << &c << endl;
    27. c += 10;
    28. }
    29. //4. 传入类函数
    30. class A
    31. {
    32. public:
    33. void func4(int a)
    34. {
    35. //阻塞当前线程执行,至少经过指定的 sleep_duration
    36. std::this_thread::sleep_for(std::chrono::seconds(1));
    37. cout << "thread:" << name_ << ", fun4 a = " << a << endl;
    38. }
    39. void func4(string str)
    40. {
    41. 阻塞当前线程执行,至少经过指定的 sleep_duration
    42. //std::this_thread::sleep_for(std::chrono::seconds(1));
    43. cout << "thread:" << name_ << ", fun4 str = " << str << endl;
    44. }
    45. void setName(string name) {
    46. name_ = name;
    47. }
    48. void displayName() {
    49. cout << "this:" << this << ", name:" << name_ << endl;
    50. }
    51. void play()
    52. {
    53. std::cout << "play call!" << std::endl;
    54. }
    55. private:
    56. string name_;
    57. };
    58. //5. detach
    59. void func5()
    60. {
    61. cout << "func5 into sleep " << endl;
    62. std::this_thread::sleep_for(std::chrono::seconds(1));
    63. cout << "func5 leave " << endl;
    64. }
    65. // 6. move
    66. void func6()
    67. {
    68. cout << "this is func6 !" << endl;
    69. }
    70. int main()
    71. {
    72. // 1 传入0个值
    73. cout << "\n\n main1--------------------------\n";
    74. std::thread t1(func1); // 只传递函数
    75. t1.join();
    76. // 2 传入2个值
    77. cout << "\n\n main2--------------------------\n";
    78. int a =10;
    79. int b =20;
    80. std::thread t2(func2, a, b); // 加上参数传递,可以任意参数
    81. t2.join();
    82. std::thread t2_1((void(*)(int, int)) func2_1, a, b); // 加上参数传递,可以任意参数
    83. t2_1.join();
    84. std::thread t2_2((int(*)(string, string)) func2_1, "darren", " and mark"); // 加上参数传递,可以任意参数
    85. t2_2.join();
    86. // 3. 传入引用
    87. cout << "\n\n main3--------------------------\n";
    88. int c =10;
    89. std::thread t3(func3, std::ref(c)); // std::ref 加上参数传递,可以任意参数
    90. t3.join();
    91. cout << "main3 c = " << &c << ", "<<c << endl;
    92. //4. 传入类函数
    93. //重载
    94. cout << "\n\n main4--------------------------\n";
    95. A * a4_ptr = new A();
    96. a4_ptr->setName("kaka");
    97. std::thread t41((void(A::*)(int)) & A::func4, a4_ptr, 100); // 重载void func4(int a)
    98. t41.join();
    99. delete a4_ptr;
    100. //重载
    101. cout << "\n\n main4--------------------------\n";
    102. A* a4_ptr_2 = new A();
    103. a4_ptr_2->setName("king");
    104. std::thread t42((void(A::*)(string)) & A::func4, a4_ptr_2, "king"); // 重载 int func4(string str)
    105. t42.join();
    106. delete a4_ptr_2;
    107. // 5.detach
    108. cout << "\n\n main5--------------------------\n";
    109. std::thread t5(func5); // 只传递函数
    110. t5.detach(); // 脱离
    111. cout << "pid: " << t5.get_id() << endl; // t5此时不能管理线程了
    112. cout << "joinable: " << t5.joinable() << endl; // false 判断线程是否可以加入等待
    113. //t5.join();出错
    114. std::this_thread::sleep_for(std::chrono::seconds(2)); // 如果这里不休眠会怎么样
    115. cout << " main5 end\n";
    116. // 6.move
    117. cout << "\n\n main6--------------------------\n";
    118. int x = 10;
    119. thread t6_1(func6);
    120. thread t6_2(std::move(t6_1)); // t6_1 线程失去所有权
    121. t6_1.join(); // 抛出异常 after throwing an instance of 'std::system_error'
    122. t6_2.join();
    123. return 0;
    124. }

     

    线程封装 

    zero_thread.h

    1. #ifndef ZERO_THREAD_H
    2. #define ZERO_THREAD_H
    3. #include
    4. class ZERO_Thread
    5. {
    6. public:
    7. ZERO_Thread(); // 构造函数
    8. virtual ~ZERO_Thread(); // 析构函数
    9. bool start();
    10. void stop();
    11. bool isAlive(); // 线程是否存活.
    12. std::thread::id id() { return th_->get_id(); }
    13. std::thread* getThread() { return th_; }
    14. void join(); // 等待当前线程结束, 不能在当前线程上调用
    15. void detach(); //能在当前线程上调用
    16. protected:
    17. void threadEntry();
    18. virtual void run() = 0; // 运行
    19. protected:
    20. bool running_; //是否在运行
    21. std::thread *th_;
    22. };
    23. #endif // ZERO_THREAD_H

    zero_thread.cpp

    1. #include "1-2-zero_thread.h"
    2. #include <sstream>
    3. #include <iostream>
    4. #include <exception>
    5. ZERO_Thread::ZERO_Thread():
    6. running_(false), th_(NULL)
    7. {
    8. }
    9. ZERO_Thread::~ZERO_Thread()
    10. {
    11. if(th_ != NULL)
    12. {
    13. //如果到调用析构函数的时候,调用者还没有调用join则触发detach,此时是一个比较危险的动作,用户必须知道他在做什么
    14. if (th_->joinable())
    15. {
    16. std::cout << "~ZERO_Thread detach\n";
    17. th_->detach();
    18. }
    19. delete th_;
    20. th_ = NULL;
    21. }
    22. std::cout << "~ZERO_Thread()" << std::endl;
    23. }
    24. bool ZERO_Thread::start()
    25. {
    26. if (running_)
    27. {
    28. return false;
    29. }
    30. try
    31. {
    32. th_ = new std::thread(&ZERO_Thread::threadEntry, this);
    33. }
    34. catch(...)
    35. {
    36. throw "[ZERO_Thread::start] thread start error";
    37. }
    38. return true;
    39. }
    40. void ZERO_Thread::stop()
    41. {
    42. running_ = false;
    43. }
    44. bool ZERO_Thread::isAlive()
    45. {
    46. return running_;
    47. }
    48. void ZERO_Thread::join()
    49. {
    50. if (th_->joinable())
    51. {
    52. th_->join(); // 不是detach才去join
    53. }
    54. }
    55. void ZERO_Thread::detach()
    56. {
    57. th_->detach();
    58. }
    59. void ZERO_Thread::threadEntry()
    60. {
    61. running_ = true;
    62. try
    63. {
    64. run(); // 函数运行所在 调用子类的run函数
    65. }
    66. catch (...)
    67. {
    68. running_ = false;
    69. throw;
    70. }
    71. running_ = false;
    72. }

    main.cpp

    1. #include <iostream>
    2. #include <chrono>
    3. #include "1-2-zero_thread.h"
    4. using namespace std;
    5. class A: public ZERO_Thread
    6. {
    7. public:
    8. void run()
    9. {
    10. while (running_)
    11. {
    12. cout << "print A " << endl;
    13. std::this_thread::sleep_for(std::chrono::seconds(5));
    14. }
    15. cout << "----- leave A " << endl;
    16. }
    17. };
    18. class B: public ZERO_Thread
    19. {
    20. public:
    21. void run()
    22. {
    23. while (running_)
    24. {
    25. cout << "print B " << endl;
    26. std::this_thread::sleep_for(std::chrono::seconds(2));
    27. }
    28. cout << "----- leave B " << endl;
    29. }
    30. };
    31. int main()
    32. {
    33. {
    34. A a;
    35. a.start();
    36. B b;
    37. b.start();
    38. std::this_thread::sleep_for(std::chrono::seconds(5));
    39. a.stop();
    40. a.join(); // join之前不去stop
    41. b.stop();
    42. b.join(); // 需要我们自己join
    43. }
    44. cout << "Hello World!" << endl;
    45. return 0;
    46. }

  • 相关阅读:
    Java安全之深入了解SQL注入
    【JVM基础14】——垃圾回收-强引用、软引用、弱引用、虚引用的区别
    海外社媒账号如何运营安全稳定?
    2023气传导耳机排行榜,盘点相对比较好用的气传导耳机分享
    【每日一题】43. 字符串相乘
    二进制逻辑运算和基本门电路
    win10升级到win11后电脑睡眠后发热严重
    一文深入理解高并发服务器性能优化
    阿里云产品试用系列-容器服务 Serverless AIGC
    Stimulsoft Ultimate Reports 2022.3.1
  • 原文地址:https://blog.csdn.net/kakaka666/article/details/127912594