一个Scope thread的实现,以及使用它的好处

Scope Thread 的实现

Scope Thread(有时也称为 Scoped Thread)是一个管理线程生命周期的类,确保线程在超出作用域时自动被 join(或 detach),从而避免手动管理线程的麻烦,防止忘记 join 或 detach 导致的程序异常(如 std::terminate)。

我们可以通过RAII(Resource Acquisition Is Initialization)的思想来实现 ScopeThread,即在对象构造时启动线程,在对象析构时自动 join 线程。

下面是一个简单的 ScopeThread 实现:

#include <iostream>
#include <thread>
#include <utility>  // for std::moveclass ScopeThread {
public:// 构造函数,接受一个可调用对象作为线程函数template<typename Callable, typename... Args>explicit ScopeThread(Callable&& func, Args&&... args): thread_(std::forward<Callable>(func), std::forward<Args>(args)...) {}// 禁止复制ScopeThread(const ScopeThread&) = delete;ScopeThread& operator=(const ScopeThread&) = delete;// 允许移动ScopeThread(ScopeThread&& other) noexcept: thread_(std::move(other.thread_)) {other.thread_ = std::thread();  // 置空原线程}ScopeThread& operator=(ScopeThread&& other) noexcept {if (this != &other) {if (thread_.joinable()) {thread_.join();  // 或 detach()}thread_ = std::move(other.thread_);other.thread_ = std::thread();  // 置空原线程}return *this;}// 析构函数,自动 join 线程~ScopeThread() {if (thread_.joinable()) {thread_.join();  // 或根据需求使用 detach()}}// 提供获取原始 std::thread 对象的接口std::thread& get() noexcept {return thread_;}const std::thread& get() const noexcept {return thread_;}private:std::thread thread_;
};// 示例用法
int main() {ScopeThread scopeThread([]() {std::cout << "Thread is running" << std::endl;});std::cout << "Main thread is running concurrently with the ScopeThread" << std::endl;// 不需要显式调用 join 或 detach,ScopeThread 会在析构时自动处理return 0;
}

实现说明

  1. 构造函数:接受一个可调用对象(函数、lambda表达式、std::bind的结果等)和参数,并使用 std::forward 转发参数给 std::thread。
  2. 禁止复制:为了避免多个 ScopeThread 对象管理同一个线程,复制构造函数和赋值运算符被删除。
  3. 移动支持:允许移动构造和移动赋值,确保线程资源可以安全转移。移动后原对象的 std::thread 被置空。
  4. 析构函数:如果线程是 joinable 的(即没有被 join 或 detach),析构时自动 join 线程。如果希望线程在后台运行,可以在析构前手动 detach 或修改析构逻辑为 detach。

使用 ScopeThread 的好处

  1. 自动资源管理:通过 RAII 机制,确保线程在作用域结束时自动 join,避免了忘记 join 或 detach 导致程序崩溃(如 std::terminate 被调用)。
  2. 减少手动操作:开发者不需要显式管理线程的生命周期,特别是在有多个退出点或异常处理的场景中,避免了复杂的错误处理逻辑。
  3. 代码简洁性:使用 ScopeThread 可以使代码更加简洁,逻辑更加清晰,减少了线程管理相关的样板代码。
  4. 异常安全性:如果代码中抛出异常,ScopeThread 仍然会在析构时被join。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/463241.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AJ-Report:一款开源且非常强大的数据可视化大屏和报表工具

嗨&#xff0c;大家好&#xff0c;我是小华同学&#xff0c;关注我们获得“最新、最全、最优质”开源项目和工作学习方法 AJ-Report是一个基于Java的开源报表工具&#xff0c;它集成了ECharts、Ant Design Vue等前端技术&#xff0c;致力于为企业提供一站式的数据可视化解决方案…

论文阅读:MultiUI 利用网页UI进行丰富文本的视觉理解

《HARNESSING WEBPAGE UIS FOR TEXT-RICH VISUAL UNDERSTANDING》 利用网页UI进行丰富文本的视觉理解 总结 grounding和QA部分的数据集占比较大、同时消融实验显示其作用相对较大&#xff0c;并且grounding部分作用和效果呈现scaling正相关提供了很多web数据处理成多模态训练…

微服务设计模式 - 断路器模式 (Circuit Breaker Pattern)

微服务设计模式 - 断路器模式 (Circuit Breaker Pattern) 定义 断路器模式&#xff08;Circuit Breaker Pattern&#xff09;是云计算和微服务架构中的一种保护性设计模式&#xff0c;其目的是避免系统中的调用链出现故障时&#xff0c;导致系统瘫痪。通过断路器模式&#xff…

roberta融合模型创新中文新闻文本标题分类

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

win11安装安卓apk原生应用,并设置网络代理

一、win11安装安卓apk原生应用&#xff0c;查看https://blog.csdn.net/qq_33704787/article/details/123658419https://blog.csdn.net/qq_33704787/article/details/123658419 主要是安装&#xff1a;Windows Subsystem for Android™ with Amazon Appstore 二、使用ABD工具设…

计算机网络(Ⅵ)应用层原理

一些网络应用的例子: E-mail Internaet电话 Web 电子支付 文本信息 搜索 P2P文件共享 流媒体 即时通讯 实时电视会议 .... .... 创建一个网络应用&#xff1a; 1.编程 2.在不同的端系统上运行。 网络应用的体系架构 可能的应用架构 1.客户-服…

【调优方法】——warmup预热

文章目录 什么是warmup?为什么引入warmup&#xff1f;warmup策略1. 线性warmup&#xff08;虚线&#xff09;2. 指数warmup&#xff08;点划线&#xff09; warmup改进参考文献 什么是warmup? warmup是一种学习率预热的方法&#xff0c;是指在训练开始时使用较小的学习率&am…

【Java笔记】1-JDK/JRE/JVM是个啥?

JDK、JRE、JVM可以说是入门必须了解的三个词汇 先说全称 JDK&#xff1a;Java Development Kit&#xff0c;Java开发工具包 JRE&#xff1a;Java Runtime Environment&#xff0c;Java运行环境 JVM&#xff1a;Java Virtual Machine&#xff0c;Java虚拟机 再说关系 JVM⊆J…

阿里云docker安装禅道记录

docker network ls docker network create -d bridge cl_network sudo docker run --name zentao --restart always -p 9982:80 --networkcl_network -v /data/zentao:/data -e MYSQL_INTERNALtrue -d hub.zentao.net/app/zentao:18.5 参考&#xff1a;用docker安装禅道…

uniapp iOS打包证书过期——重新下载证书及更新文件

证书过期&#xff0c;重新生成步骤 关于所需的证书、标识符、描述文件等请查看iOS打包证书申请流程证书有效期为1年 过期提示 生成证书 点击 钥匙串访问 → 证书助理 → 从证书颁发机构请求证书 &#xff1b; 我这里选择 存储到磁盘 &#xff0c;邮件、名称 可自定义&#…

Pandas 数据清洗

1.数据清洗定义 数据清洗是对一些没有用的数据进行处理的过程。很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况&#xff0c;如果要使数据分析更加准确&#xff0c;就需要对这些没有用的数据进行处理。 2.清洗空值 DataFrame.dropna(axis0, howany, threshN…

数据结构与算法(1)

一&#xff1a;文章总体结构内容解读 二&#xff1a;绪论 1.1研究&#xff1a; 1.范围 数据结构是一门研究非数值计算的程序设计中计算机的操作对象以及它们之间的关系和操作的学科&#xff1b; 2.计算机解决问题步骤&#xff1a; 1.2基本概念和术语&#xff1a; 1.数据、…

RNN与Self-Attention

文章目录 1. SimpleRNN1.1 h t h_t ht​计算1.2 激活函数 2. SimpleRNNSelf-Attention2.1 状态更新2.2 权重 α α α 1. SimpleRNN 学习视频&#xff1a;https://www.youtube.com/watch?vCc4ENs6BHQw&t0s 对于时序数据&#xff0c;输入输出都不固定&#xff0c;需要ma…

Vue指令:v-show、v-if

目录 1.v-show:频繁控制显示隐藏 v-if:要么显示&#xff0c;要么隐藏 2.网页渲染效果 3.flag:true 4.若flag:false&#xff0c;则 5.底层原理&#xff1a; 1.v-show:频繁控制显示隐藏 v-if:要么显示&#xff0c;要么隐藏 <!DOCTYPE html> <html lang"en&…

在Springboot中更好的打印日志

说明 我的系统缺乏一些日志打印,但我并不想显式的在我的业务代码中使用Slf4j注解,因为这会造成我无法关注我的业务代码逻辑,因为通常来说,10行业务代码 你可以就需要3-4行log.info来打印日志 是的,这样代码很难看,所以我使用了Aop 拦截器 面向对象 threadLoacl等技术来设计我…

进程间通信小练习

[!info] 编写程序 创建两个进程&#xff1a; 父进程执行文件拷贝操作。如果接收到SIGUSR1信号&#xff0c;将打印出当前拷贝进度。 子进程每隔一个固定时间向父进程发生SIGUSR1信号。 vi src.txt然后输几十个字 然后新建源程序 #include <stdio.h> #include <stdli…

NVR小程序接入平台/设备EasyNVR多个NVR同时管理多平台级联与上下级对接的高效应用

政务数据共享平台的建设正致力于消除“信息孤岛”现象&#xff0c;打破“数据烟囱”&#xff0c;实现国家、省、市及区县数据的全面对接与共享。省市平台的“级联对接”工作由多级平台共同构成&#xff0c;旨在满足跨部门、跨层级及跨省数据共享的需求&#xff0c;推动数据流通…

wait()方法和notify()方法

由于操作系统对线程的调度是随机执行的&#xff0c;且线程之间是抢占式执行的&#xff0c;因此线程之间执行的先后顺序难以预知。但是&#xff0c;有时候在实际开发中&#xff0c;我们希望合理的协调多个线程之间的先后执行顺序。在Java中&#xff0c;wait()方法和notify()方法…

搭建 EwoMail 邮件服务器

EwoMail简介 EwoMail是基于Linux的开源邮件服务器&#xff0c;支持一键搭建&#xff0c;集成了众多优秀稳定的组件&#xff0c;是一个快速部署、简单高效、安全稳定的邮件解决方案&#xff0c;支持电脑和手机的客户端&#xff0c;适合个人或邮箱功能需求少的企业。 非常稳定&…

ST算法解RMQ问题

题目 代码 #include <bits/stdc.h> using namespace std; const int N 2e510, M 20; int st[N][M]; int n, m; int main() {ios::sync_with_stdio(0);cin.tie(0);cin >> n;for(int i 1; i < n; i)cin >> st[i][0];for(int i 1; (1 << i) < …