基于Linux pthread库模拟实现的线程类

发布时间:2026/10/7 21:38:08

基于Linux pthread库模拟实现的线程类 基于Linux pthread库模拟实现的线程类线程类的本质对线程生命周期的控制线程创建线程属性获取线程等待int(void*) 线程v1.0参考void(T)线程v1.1参考线程类的本质无论什么语言的线程类只要它还在当前计算机中运行就必须调用计算机中原有的原生线程库内的接口对线程进行控制。所以所谓的封装使用的还是原生线程但会根据实际需求例如安全、效率等对创建的线程进行控制。这里模仿 C11 的thread类对线程类进行描述希望一个线程有自己的线程ID。希望线程有自己的线程名。用户可能希望查看当前线程的运行状态。线程拥有属于自己的线程函数。线程可由用户决定何时启动。线程运行结束后不建议可选返回自己的返回值。因为函数有void和其他返回值类型这使得功能实现上变得很复杂。其他可选一般情况下不希望线程自己进行隐式构造一个线程。线程支持移动构造但不能支持拷贝构造。对线程生命周期的控制线程创建这里我们希望线程类的对象能根据用户的需求选择是否创建。所以构造函数只会对线程的基本信息赋值对象真正创建线程还需要调用额外的函数这里可设置接口start。若线程启动成功则设置状态runstate为真。线程属性获取这里的线程类的属性有 3 种线程名。线程运行状态。线程 ID 。分别给不同的属性设置接口即可。线程等待线程和进程一样若线程已经退出则默认返回时会被等待。所以可通过设置等待用的接口join通过pthread_join使得主线程等待子线程。若线程状态变量runstate为假则说明等待成功join返回真。否则join所在的线程会进行等待修改等待结果并返回。int(void*)线程v1.0参考mythread.hpp#pragmaonce#includefunctional#includepthread.h#includestringusingstd::string;// 想让线程的主体函数和main函数一样的运行模式namespacemystd{usingfunc_tstd::functionint(void*);templateclassTclassMyThread{public:MyThread(conststringname,func_t fc,T dataT()):_name(name),_func(fc),_data(data),_tid(pthread_t()),_runstate(false){}~MyThread(){}staticvoid*ThreadRoutine(void*args){// 通过类内方法启动进程// 因为原生线程库无法上传包装器MyThread*tsstatic_castMyThread*(args);ts-_func(args);returnnullptr;}boolstart(){if(pthread_create(_tid,nullptr,ThreadRoutine,this)0){_runstatetrue;returntrue;}returnfalse;}booljoin(){// 线程正常退出if(!_runstate)returntrue;// 主动等待线程// 可以获取返回值现在是模型所以不考虑设为nullptrif(pthread_join(_tid,nullptr)0){_runstatefalse;returntrue;}// 等待失败returnfalse;}// getter接口boolrunstate()const{return_runstate;}stringname()const{return_name;}pthread_ttid()const{return_tid;}private:pthread_t _tid;// 线程IDstring _name;// 线程名bool_runstate;// 线程运行状态func_t _func;// 线程本体函数T _data;// 线程类初始数据};}// namespace mystd测试参考#includemythread.hpp// 为使用mt19937#includechrono#includeiostream#includerandom#includeunistd.h#includevectorusingmystd::MyThread;usingstd::cout;usingstd::endl;usingstd::to_string;usingstd::vector;intf(void*args){sleep(1);MyThreadint*mtdstatic_castMyThreadint*(args);coutmtd-name(), 启动endl;// 精度更高的随机数类std::mt19937_64rng(std::chrono::steady_clock().now().time_since_epoch().count());for(inti1,x0;i5;i){xrng()%100001;coutxendl;sleep(1);}return0;}voidf1(){MyThreadintmyThread(thread1,f);if(myThread.start()){cout主线程thread1运行成功, 运行状态myThread.runstate()endl;}else{cout主线程thread1运行失败\n;}if(myThread.join()){cout主线程等待thread1成功, 运行状态myThread.runstate()endl;}else{cout主线程等待thread1失败\n;}}voidf2(){vectorMyThreadintts;for(inti1;i5;i){string nameThreadto_string(i);ts.push_back(MyThreadint(name,f));}for(autox:ts){if(!x.start()){coutx.name()启动异常\n;exit(-1);}sleep(1);}for(autox:ts){if(!x.join()){coutx.name()回收异常\n;exit(-1);}coutx.name()成功回收\n;}}intmain(){f2();return0;}void(T)线程v1.1参考mythread.hpp#pragmaonce#includefunctional#includepthread.h#includestringnamespacemystd{usingstd::function;usingstd::string;// 因为线程函数的返回值从始至终都没有使用// 所以直接上传返回值为void的函数templateclassTusingfunc_tfunctionvoid(T);// 创造一个支持选择参数类型的线程类模板templateclassTclassMyThread{private:pthread_t _tid;// 线程IDstring _name;// 线程名bool_runstate;// 线程运行状态func_tT_func;// 线程本体函数T _data;// 计划上传给线程本体函数的参数public:explicitMyThread(conststringname,func_tTfc,T data):_tid(pthread_t()),_name(name),_runstate(false),_func(fc),_data(data){}~MyThread(){}staticvoid*ThreadRoutine(void*args){// args一般情况下为线程对象MyThread*tstatic_castMyThread*(args);t-_func(t-_data);returnnullptr;}boolstart(){if(pthread_create(_tid,nullptr,ThreadRoutine,this)0){return_runstatetrue;}returnfalse;}booljoin(){if(!_runstate)returntrue;if(pthread_join(_tid,nullptr)0){_runstatefalse;returntrue;}returnfalse;}// getter接口boolrunstate()const{return_runstate;}stringname()const{return_name;}pthread_ttid()const{return_tid;}};}// namespace mystd测试程序#includemythread.hpp#includeiostream#includestring#includevectorusingnamespacestd;usingnamespacemystd;structThreadData{vectorint_arr;int*_sum;ThreadData(vectorintarr,int*sum):_arr(arr),_sum(sum){}};voidadd(void*args){vectorintarrstatic_castThreadData*(args)-_arr;int*sumstatic_castThreadData*(args)-_sum;for(autox:arr)(*sum)x;}intmain(){vectorinta{1,1,4,5,1,4,0,9,0,9,8,1,0};intsum0;ThreadDatadt(a,sum);string ThreadNamet1;MyThreadThreadData*t1(ThreadName,add,dt);if(t1.start()){if(!t1.join())return-1;}coutsumendl;return0;}但若编译器支持 C11 还是建议使用thread。
延伸阅读

更多相关文章

2026/9/26 15:18:49

AI辅助开发实战:信息安全专业毕业设计高效工程化路径

1. 项目概述:当信安毕设遇上AI辅助开发又到了一年一度的毕业季,对于信息安全相关专业的同学来说,毕业设计(毕设)无疑是大学阶段最具挑战性的综合考核。它不再是对单一知识点的考察,而是要求你将网络攻防、系…

2026/10/7 10:01:05

2026ai站点开发系统有哪些,这几个可千万别错过啦!

2026ai站点开发系统有哪些,这几个可千万别错过啦!艾瑞咨询《2026年中国企.业数字化建站行业白皮书》数据显示,国内AI建站渗透率已破68%,但抽样超1200家中小企业里,仅31%在生成站点后半年仍持续续费且搜索流量正向增长。…

2026/10/1 18:14:39

BilibiliDown终极指南:轻松下载B站视频和高质量音频的完整教程

BilibiliDown终极指南:轻松下载B站视频和高质量音频的完整教程 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_m…

2026/10/7 21:37:04

Java课程设计在线投票系统实战指南

简介:本资源是一套完整的Java课程设计级在线投票系统源码,面向高校计算机专业学生及Java初学者,用于实践Web开发全流程,涵盖用户登录、投票管理、结果统计等核心功能模块。压缩包共119个文件,包含18个Java业务逻辑类、…

2026/10/7 21:37:04

C++ STL queue深度解析:容器适配器、底层deque与性能优化

聊到C STL,很多人觉得queue这个容器适配器简单到没什么可聊的——创建队列、push、front、pop,刷题和应付考试全靠它。但我在实际项目里见过不少queue相关的bug,也踩过把queue用出性能问题的坑。C STL的queue远不止“先进先出”这四个字那么简…

2026/10/7 21:37:04

DeepSeek Harness 插件开发实战:从环境搭建到团队落地

1. 从零理解 DeepSeek Harness 插件体系1.1 这个工具到底解决什么问题第一次接触 DeepSeek Harness 的人,最容易犯的错就是把它当成一个普通的聊天客户端。实际上它更像是一个"AI 能力调度中枢"——把模型调用、文件读写、终端执行、代码检索这些能力拆成…

2026/10/7 21:32:03

企业级网络入侵检测系统实战:流量特征工程与双模型部署

简介:本资源是一个基于深度学习与机器学习的网络入侵检测系统(NIDS)完整项目实现,面向网络安全工程师、高校信息安全专业学生及AI安全方向研究者,旨在解决传统签名检测难以识别未知攻击(如DDoS、SQL注入、恶…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/7 8:18:33

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/6 17:46:51

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:05:03

ESP32免重刷固件:浏览器直接修改NVS键值实现WiFi配置更新

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:05:03

SAP HANA查询结果导出CSV:避开乱码、性能与权限的实用指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:05:03

数字后端Placement阶段Density与Congestion控制实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑