C++11线程库

C++11也提供了对应的线程库,在头文件<thread>中;C++11将其封装成thread类,通过类实例化出对象,调用类内成员方法进行线程控制。

#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;
void func()
{int cnt = 3;while(cnt--){cout<<"thread : "<<cnt<<endl;sleep(1); }
}
int main()
{thread td(func);//创建线程sleep(5);td.detach();//线程分离td.join();//线程等待return 0;
}

线程封装

C++11实现的线程thread是对pthread库的封装,这里也对pthread库做简单封装;

首先要封装实现一个thread类,其中要包括成员变量:线程ID、分离状态(detach)、运行状态(runing)、返回值、线程名称等等

namespace mypthread
{class thread{public:private:pthread_t _tid;std::string _name;bool _detach;bool _runing;void* retval;};
}

构造函数(创建线程)

C++thread一样,在创建对象时就将线程要执行的方法传入,那在thread类中,就要存在一个成员变量func(没有参数、没有返回值的)

这里就要使用C++11语法:function包装器

using func = std::function<void(void)>;这样在类内定义void(void)类型的成员变量。

但是,我们知道,在调用pthread_create创建线程时,要传递的函数类型是(void*(void*))类型的,所以就还要存在一个void*(void*)类型的函数;我们可以将该方法实现成静态成员函数

但是,这个函数还要可以访问thread类内成员func,静态成员函数没有隐藏的this指针,这里可以将this作为参数传递给线程要调用的方法(pthread_create第四个参数)

namespace mypthread
{static int count = 1;using func = std::function<void(void)>;class thread{static void *routine(void *msg){// 传递的是this指针thread *td = static_cast<thread *>(msg);std::cout << td->_name << std::endl;// 调用funtd->_fun();return (void *)100;}public:thread(func fun) : retval(nullptr), _fun(fun), _detach(false){_name = "thread-" + std::to_string(count);count++;int n = pthread_create(&_tid, nullptr, routine, (void *)this);if (n != 0){std::cerr << "pthread_create" << std::endl;}_runing = true;}private:pthread_t _tid;std::string _name;bool _detach;bool _runing;void *retval;func _fun;};
}

这里为了方便测试,存在一个count计数器,为了生成线程名称_name

线程分离

在创建线程之后,我们可以设置线程分离;

        void Detach(){if(_detach)return;pthread_detach(_tid);_deatch = true;}

线程取消

我们可以调用pthread_cancel来取消线程;

        bool Cancel(){if (_runing == false)return;int n = pthread_cancel(_tid);if (n != 0){std::cerr << "pthread_cancel" << std :: endl;return false;}return true;}

线程等待

新创建的线程在运行结束后,需要进行线程等待;这里实现就直接调用pthread_join阻塞等待线程;然后将线程的返回值放到_retval中。

      void Join(){pthread_join(_tid, &_retval);}

析构函数(回收线程)

pthread库进行面向对象封装,在thread析构函数中,就要调用线程取消Cancel,然后调用Join回收线程并获取线程的返回值。

        ~thread(){Cancel();Join();}

测试thread

using namespace mypthread;
void test()
{int cnt = 3;while (cnt--){std::cout << "new thread : " << cnt << std::endl;sleep(1);}
}
int main()
{thread td(test);sleep(5);return 0;
}

在这里插入图片描述

这样在main函数中,就算我们没有显示调用Join等待,在线程thread对象出了作用域后,自动调用析构函数从而调用CancelJoin回收线程。

番外

对于线程封装,这里实现了另外一种版本:

在创建thread对象之后并不会立即创建新线程,而是调用Start才会创建新线程;

此外我们可以在没有创建线程时设置detach分离状态,也可以在线程运行时设置detach分离状态;

namespace mythread
{static int count = 1;using func_t = std::function<void()>;class Thread{static void *rontinue(void *args){Thread *pt = static_cast<Thread *>(args);pt->_fun();return (void*)pt->_name.c_str();}void EnableDetach() { _detach = true; }void EnableRuning() { _runing = true; }public:Thread(func_t fun) : _tid(-1), _detach(false), _runing(false), _fun(fun), _retval(nullptr){_name = "thread- " + std::to_string(count);count++;}void Start(){if (_runing)return;// 创建线程int n = pthread_create(&_tid, nullptr, rontinue, this);if (n != 0){std::cerr << "pthread_create" << std::endl;exit(1);}EnableRuning();Detach();}void Detach(){if (_detach){if (_runing){pthread_detach(_tid);}EnableDetach();}}void Cancel(){if (_runing){pthread_cancel(_tid);}_runing = false;}void Join(){if (_detach)return;pthread_join(_tid, &_retval);}std::string GetName(){return _name;}private:pthread_t _tid;    // 线程idstd::string _name; // 线程名bool _detach;      // 分离状态bool _runing;      // 运行状态func_t _fun;         // 线程执行函数void *_retval;     // 返回值};
}

简单总结:

本篇文章对pthread库做了简单封装,实现了简单的thread类。

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

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

相关文章

安全防御-SCDN如何保护网站安全

随着互联网的快速发展&#xff0c;越来越多的企业依赖在线服务来运行其核心业务。与此同时&#xff0c;网络攻击的频率和复杂性也在不断增加&#xff0c;恶意流量成为许多企业头疼的问题。为了有效地提高网站的安全性和稳定性&#xff0c;德迅云安全加速SCDN被许多用户关注。今…

运筹优化(OR)-在机器学习(ML)浪潮中何去何从?

在如今机器学习的浪潮中&#xff0c;机器学习相关的岗位日益增多&#xff0c;而运筹优化的岗位却相对较少。这是今年我秋招过程中看到的现象。企业越来越希望候选人不仅能建模求解&#xff0c;还能理解如何用数据驱动优化。需要我们有一个完整的技术栈。那么我们就来看看OR与ML…

GitHub Copilot 在 VS Code 上的终极中文指南:从安装到高阶玩法

GitHub Copilot 在 VS Code 上的终极中文指南&#xff1a;从安装到高阶玩法 前言 GitHub Copilot 作为 AI 编程助手&#xff0c;正在彻底改变开发者的编码体验。本文将针对中文开发者&#xff0c;深度解析如何在 VS Code 中高效使用 Copilot&#xff0c;涵盖基础设置、中文优化…

安全测试、web探测、httpx

&#x1f4a2; 简介 httpx 是一个快速且多用途的HTTP工具包&#xff0c;允许使用retryablehttp库运行多个探测器。它旨在通过增加线程数量来保持结果的可靠性。 功能 &#x1f92a; 发送 GET、POST、PUT、DELETE 等 HTTP 请求支持流式传输支持重定向支持身份验证支持代理支持 …

CNN 中 3×3 卷积核等设计背后的底层逻辑

为什么卷积核爱用 33&#xff1f;CNN 设计 “约定俗成” 的底层逻辑 做深度学习的同学&#xff0c;对 CNN 里 33 卷积核、最大池化、BN 层这些设计肯定不陌生&#xff0c;但你有没有想过&#xff1a;为啥卷积核总选 33&#xff1f;池化层为啥默认最大池化&#xff1f;BN 层又是…

税务岗位职场能力解析与提升路径规划

税务岗位作为企业运营的核心环节之一&#xff0c;对从业者的专业能力与综合素质要求极高。从基础税务核算到战略税务筹划&#xff0c;职场能力的提升需要系统化的路径规划。以下从核心能力、阶段化提升路径及证书价值三个维度展开分析。核心能力体系构建专业税务能力是基础&…

MySQL 索引:结构、对比与操作实践指南

MySQL系列 文章目录MySQL系列前言案例一、认识MySQL与磁盘1.1 MySQL与存储1.2 MySQL 与磁盘交互基本单位二、 MySQL 数据交互核心&#xff1a;BufferPool 与 IO 优化机制三、索引的理解3.1 测试案例3.2 page3.3 页目录3.3 对比其他结构四、聚簇索引 VS 非聚簇索引五、索引操作5…

GitHub 热榜项目 - 日榜(2025-08-24)

GitHub 热榜项目 - 日榜(2025-08-24) 生成于&#xff1a;2025-08-24 统计摘要 共发现热门项目&#xff1a;20 个 榜单类型&#xff1a;日榜 本期热点趋势总结 本期GitHub热榜呈现三大技术热点&#xff1a;1&#xff09;AI应用爆发式创新&#xff0c;包括神经拟真伴侣&#…

纯净Win11游戏系统|24H2专业工作站版,预装运行库,无捆绑,开机快,游戏兼容性超强!

哈喽&#xff0c;大家好&#xff01; 今天给大家带来一款 Windows 11 游戏版本系统镜像&#xff0c;软件已放在文章末尾&#xff0c;记得获取。 一、软件获取与启动 解压后双击exe即可直接运行&#xff0c;无需额外安装。首次启动界面简洁&#xff0c;引导清晰。 二、系统选…

CI/CD 学习之路

目录 简介&#xff1a; 1、工具介绍&#xff1a; 2、搭建jenkins 1&#xff09;创建一个文件Dockerfile&#xff0c;文件无后缀&#xff0c;写入以下代码 2&#xff09;在Dockerfile文件所在目录执行&#xff08;my-jenkins-android 未自定义镜像名称&#xff09; 3&#xf…

马斯克宣布开源Grok 2.5:非商业许可引争议,模型需8×40GB GPU运行,Grok 3半年后开源

昨晚&#xff0c;马斯克在 X 平台连续发布多条消息&#xff0c;宣布其人工智能公司 xAI 已正式开源 Grok 2.5 模型。这款模型是 xAI 在 2024 年的主力模型&#xff0c;如今完全向公众开放。与此同时&#xff0c;马斯克还预告了下一代模型 Grok 3 的开源计划&#xff0c;预计将在…

DMP-Net:面向脑组织术中成像的深度语义先验压缩光谱重建方法|文献速递-深度学习人工智能医疗图像

Title题目DMP-Net: Deep semantic prior compressed spectral reconstruction methodtowards intraoperative imaging of brain tissueDMP-Net&#xff1a;面向脑组织术中成像的深度语义先验压缩光谱重建方法01文献速递介绍脑肿瘤可分为原发性和继发性两类。原发性脑肿瘤多发生…

【nl2sql综述】2025最新综述解读

论文地址&#xff1a;https://arxiv.org/pdf/2408.05109 解读&#xff1a;迈向数据民主化——大型语言模型时代下的Text-to-SQL技术综述 近期&#xff0c;一篇名为《A Survey of Text-to-SQL in the Era of LLMs》的综述论文系统性地梳理了自然语言到SQL查询&#xff08;Text-t…

logback-spring.xml 文件

一.概述这是一个日志文件&#xff0c;主要用来对应用程序的日志进行记录&#xff0c;并且可以配置日志的一些格式和规则。二.读取机制1.SpingBoot自动识别进行文件扫描时&#xff0c;当在 classpath 下发现名为 logback-spring.xml 的文件时&#xff0c;Spring Boot 会自动加载…

LeetCode Hot 100 第二天

1. 283 移动零 链接&#xff1a;题目链接 题解&#xff1a; 要求&#xff1a;时间复杂度 < O (n^2) 题解&#xff1a;将非零元素依次往前移&#xff08;占据0元素的位置&#xff09;&#xff0c;最后再将0元素填充至数组尾。时间复杂度O(n)&#xff0c;用一个指针x来维护非…

04-Maven工具介绍

文章目录1、Maven官网2、Maven的3个重要功能3、Maven安装3.1 安装教程的视频3.2 安装教程的文本1、Maven官网 https://maven.apache.org/ 2、Maven的3个重要功能 黑马程序员JavaWeb基础教程&#xff0c;Java web从入门到企业实战完整版 3、Maven安装 3.1 安装教程的视频 …

基于开源 AI 智能名片链动 2+1 模式 S2B2C 商城小程序的新开非连锁品牌店开业引流策略研究

摘要&#xff1a;本文聚焦于一家新开且地理位置优越、目标客户为周边“80 后”“90 后”上班族的非连锁品牌店。在明确店铺定位、完成店内设计与菜品规划等基础工作后&#xff0c;探讨如何在新店开业初期有效打响品牌、吸引目标客户。通过引入开源 AI 智能名片链动 21 模式 S2B…

UE5多人MOBA+GAS 54、用户登录和会话创建请求

文章目录创建主菜单需要的创建主菜单游戏模式创建主菜单游戏控制器创建主菜单界面UI实现登录游戏实例创建等待界面配置和获取协调器 URL撰写和发送会话创建请求创建主菜单需要的 创建主菜单游戏模式 MainMenuGameMode 创建主菜单游戏控制器 MainMenuPlayerController #p…

SCSS上传图片占位区域样式

_App.scss// 上传图片占位区域样式---------------------------------------- [theme"uploadImage"] {transition: 0.2s;position: relative;cursor: pointer;border-radius: 4px;/*居中填满*/background-repeat: no-repeat;background-position: center;background-…

Prometheus+Grafana监控mysql

1、简述 使用 Prometheus 结合 Grafana 监控 MySQL 是一套成熟且广泛应用的方案&#xff0c;能实现对 MySQL 性能、状态等指标的实时采集、存储、可视化及告警。 2、整体架构说明 Prometheus&#xff1a;负责定时从 MySQL 采集监控指标&#xff08;需借助 Exporter&#xff0…