C++ 并发编程实战 第二章 线程管控

[复制链接]
发表于 2023-4-8 16:30:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
第二章 线程管控

std::thread 简介

构造和析构函数
  1. /// 默认构造
  2. /// 创建一个线程,什么也不做
  3. thread() noexcept;
  4. /// 带参构造
  5. /// 创建一个线程,以 A 为参数执行 F 函数
  6. template <class Fn, class... Args>
  7. explicit thread(Fn&& F, Args&&... A);
  8. /// 拷贝构造(不可用)
  9. thread(thread& Other) noexcept = delete;
  10. /// 移动构造
  11. /// 移交线程的归属权
  12. thread(thread&& x) noexcept;
  13. /// 析构函数
  14. ~thread();
复制代码
常用成员函数
  1. /// 等待线程结束并清理资源(会阻塞)
  2. void join();
  3. /// 返回线程是否可以执行 join() 成员函数
  4. bool joinable();
  5. /// 将线程与调用其的线程分离,彼此独立执行(此函数必须在线程创建时立即调用,
  6. /// 且调用此函数会使其不能被join)
  7. void detach();
  8. /// 获取线程id
  9. std::thread::id get_id();
  10. /// 见移动构造函数
  11. /// 如果对象是 joinable 的,那么会调用 std::terminate() 结果程序
  12. thread& operator=(thread&& Other) noexcept;
复制代码
使用线程类完成线程的基本管控

发起线程


  • 线程通过构建std::thread对象而启动,该对象指明线程要运行的任务。
  1. void do_some_work();
  2. std::thread my_thread(do_some_work);
复制代码

  • 对应复杂的任务,可以使用函数对象。
  1. class background_task{
  2. public:
  3.     void operator()() const{
  4.         do_something();
  5.         do_something_else();
  6.     }
  7. };
  8. background_task f;
  9. std::thread my_thread1(f);
  10. // 使用匿名函数对象
  11. // std::thread my_thread2(background_task());这样写会出错,
  12. // 编译器会解释成函数声明,返回值为 std::thread, 函数名为 my_thread2,
  13. // 函数参数为函数指针类型 background_task (*)(void), 因此改为如下两种方式:
  14. std::thread my_thread2((background_task()));
  15. // 采用新式的统一初始化语法(uniform initialization syntax,又名列表初始化)
  16. std::thread my_thread2{background_task()};
复制代码
等待线程完成

一旦启动了线程,我们就需明确是要等待它结束(与之汇合 join()),还是任由它独自运行(与之分离 detach())
  1. std::thread my_thread1(f);
  2. // ...
  3. my_thread1.join();// 等待线程结束并清理资源
复制代码
❗❗❗ 同一个线程的 .join() 方法不能被重复调用,否则程序会 abort()
对 thread 封装——thread_guard

基于 RAII 原理,对 std::thread 进行封装
[code]// std::thread 封装(基于RAII)class thread_guard{    thread& m_thread;public:    explicit thread_guard(thread& t):m_thread(t){}    ~thread_guard() {        // 检查是否joinable是有必要的,重复 join() 会出错        if (m_thread.joinable()){            m_thread.join();        }    }    // C++11 "=delete" 标记,声明拷贝构造和复制赋值操作为被删除的函数    // 防止拷贝导致重复调用 join()    thread_guard(thread_guard const&) = delete;    thread_guard& operator=(thread_guard const&) = delete;};int main(){    thread t([] {cout
继续阅读请点击广告
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表