news 2026/4/23 17:43:49

【Linux】使用C++对线程进行封装

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Linux】使用C++对线程进行封装

这里直接看代码就行:

第一个版本:

#pragma once #include <iostream> #include <functional> #include <pthread.h> namespace ThreadModule { static int gnumber = 1; using callback_t = std::function<void ()>;//重点 enum class TSTATUS//线程状态 { THREAD_NEW, THREAD_RUNNING, THREAD_STOP }; std::string StatusString(TSTATUS s) { switch (s) { case TSTATUS::THREAD_NEW: return "THREAD_NEW"; case TSTATUS::THREAD_RUNNING: return "THREAD_RUNNING"; case TSTATUS::THREAD_STOP: return "THREAD_STOP"; } return nullptr; } std::string isJoin(bool joinable) { return joinable ? "true" : "false"; } class Thread { private: void ToRuning() { _status = TSTATUS::THREAD_RUNNING; } void ToStop() { _status = TSTATUS::THREAD_STOP; } static void* ThreadRoutine(void* args)//static : 取消 this 指针对该函数的干扰 { Thread *self = static_cast<Thread*>(args); pthread_setname_np(self->_tid,self->_name.c_str());//设置线程名 self->_cb(); self->ToStop(); return nullptr; } public: Thread(callback_t cb) :_tid(-1),_status(TSTATUS::THREAD_NEW),_joinable(true),_cb(cb),_result(nullptr) { _name = "Thread_" + std::to_string(gnumber++); } ~Thread() {} bool Start() { int n = pthread_create(&_tid,nullptr,ThreadRoutine,this); if(n != 0) return false; ToRuning(); return true; } void Join() { if (_joinable) { int n = pthread_join(_tid, &_result); if (n != 0) { std::cerr << "join error: " << n << std::endl; return; } (void)_result; _status = TSTATUS::THREAD_STOP; } else { std::cerr << "error, thread join status : " << _joinable << std::endl; } } void Detach() { if(_status == TSTATUS::THREAD_RUNNING && _joinable) { pthread_detach(_tid); _joinable = false; } else std::cout << "detach " << _name << "failed" << std::endl; } void Stop() { } void Die() { if(_status == TSTATUS::THREAD_RUNNING) { pthread_cancel(_tid); _status = TSTATUS::THREAD_STOP; } } void PrintInfo() { std::cout << "thread name: " << _name << std::endl; std::cout << "thread _tid: " << _tid << std::endl; std::cout << "thread _status: " << StatusString(_status) << std::endl; std::cout << "thread _joinable: " << isJoin(_joinable) << std::endl; } private: std::string _name; pthread_t _tid; TSTATUS _status; bool _joinable; callback_t _cb;//用户自定义线程的执行函数 void* _result;//线程的退出信息 }; } // namespace ThreadModule

第二个版本:

#pragma once #include <iostream> #include <functional> #include <pthread.h> namespace ThreadModule { static int gnumber = 1; template<class T> using callback_t = std::function<void (T&)>;//重点 enum class TSTATUS//线程状态 { THREAD_NEW, THREAD_RUNNING, THREAD_STOP }; std::string StatusString(TSTATUS s) { switch (s) { case TSTATUS::THREAD_NEW: return "THREAD_NEW"; case TSTATUS::THREAD_RUNNING: return "THREAD_RUNNING"; case TSTATUS::THREAD_STOP: return "THREAD_STOP"; } return nullptr; } std::string isJoin(bool joinable) { return joinable ? "true" : "false"; } template<class T> class Thread { private: void ToRuning() { _status = TSTATUS::THREAD_RUNNING; } void ToStop() { _status = TSTATUS::THREAD_STOP; } static void* ThreadRoutine(void* args)//static : 取消 this 指针对该函数的干扰 { Thread<T> *self = static_cast<Thread<T>*>(args); pthread_setname_np(self->_tid,self->_name.c_str());//设置线程名 self->_cb(self->_data); self->ToStop(); return nullptr; } public: Thread(callback_t<T> cb,const T& data) :_tid(-1) ,_status(TSTATUS::THREAD_NEW) ,_joinable(true),_cb(cb) ,_result(nullptr) ,_data(data) { _name = "Thread_" + std::to_string(gnumber++); } ~Thread() {} bool Start() { int n = pthread_create(&_tid,nullptr,ThreadRoutine,this); if(n != 0) return false; ToRuning(); return true; } void Join() { if (_joinable) { int n = pthread_join(_tid, &_result); if (n != 0) { std::cerr << "join error: " << n << std::endl; return; } (void)_result; _status = TSTATUS::THREAD_STOP; } else { std::cerr << "error, thread join status : " << _joinable << std::endl; } } void Detach() { if(_status == TSTATUS::THREAD_RUNNING && _joinable) { pthread_detach(_tid); _joinable = false; } else std::cout << "detach " << _name << "failed" << std::endl; } void Stop() { } void Die() { if(_status == TSTATUS::THREAD_RUNNING) { pthread_cancel(_tid); _status = TSTATUS::THREAD_STOP; } } void PrintInfo() { std::cout << "thread name: " << _name << std::endl; std::cout << "thread _tid: " << _tid << std::endl; std::cout << "thread _status: " << StatusString(_status) << std::endl; std::cout << "thread _joinable: " << isJoin(_joinable) << std::endl; } private: std::string _name; pthread_t _tid; TSTATUS _status; bool _joinable; callback_t<T> _cb;//用户自定义线程的执行函数 void* _result;//线程的退出信息 T _data; }; } // namespace ThreadModule

测试封装的线程:

#include "Thread_version1.hpp" #include <unistd.h> #include <vector> class Task { public: Task(int x, int y) : _x(x), _y(y) { } void Execute() { _result = _x + _y; } void Print() { std::cout << _x << "+" << _y << "=" << _result << std::endl; } private: int _x; int _y; int _result; }; // void routine(int cnt) // { // char name[64]; // pthread_getname_np(pthread_self(),name,sizeof(name)); // int cnt = 10; // while(true) // { // std::cout << "new thread running: " << name << "count :" << std::endl; // sleep(1); // } // } int main() { //构建任务 srand(time(nullptr) ^ getpid()); const int num = 10; std::vector<Task> tasks; for(int i = 0; i < 10;i++) { tasks.emplace_back(rand()%10 + 1,3); } std::vector<ThreadModule::Thread> threads; for(int i = 0;i < 10;i++) { threads.emplace_back([i,&tasks](){ tasks[i].Execute(); }); } for(auto& t : threads) { t.Start(); } for(auto& t : threads) { t.Join(); t.PrintInfo(); } for(auto& t : tasks) { t.Print(); } //////////////////////////////////////////////////// // ThreadModule::Thread<int> t(routine,10);//关于可以传多个参数问题,可以传个类过去,这个类里面有多个类型变量 // sleep(1); // t.Start();//创建线程 // sleep(5); // t.Die();//杀掉线程 // sleep(1); // t.Join();//等待线程 // t.PrintInfo();//打印线程信息 return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 17:56:44

C# 12展开运算符实战精讲(仅限高级开发者掌握的编码黑科技)

第一章&#xff1a;C# 12集合表达式展开运算符概览 C# 12 引入了集合表达式中的展开运算符&#xff08;spread operator&#xff09;&#xff0c;允许开发者在初始化集合时更灵活地合并多个数据源。这一特性极大简化了数组、列表等集合类型的构建过程&#xff0c;特别是在需要组…

作者头像 李华
网站建设 2026/4/23 0:17:36

C#权限控制系统实战(跨平台JWT+Policy深度集成)

第一章&#xff1a;C#跨平台权限验证概述在现代软件开发中&#xff0c;C#已不再局限于Windows平台&#xff0c;借助.NET Core及后续的.NET 5版本&#xff0c;开发者能够构建真正意义上的跨平台应用。随之而来的是对权限验证机制的更高要求——如何在Linux、macOS和容器化环境中…

作者头像 李华
网站建设 2026/4/21 15:54:01

ooder-right 权限插件 0.5 版本开源发布

ooder-right 是一个基于 DDD 领域驱动设计的全栈权限管理框架&#xff0c;构建了从"文档模型前置定义"到"代码 DNA 级植入"的全栈权限体系&#xff0c;解决 AI 时代权限管理的新痛点。 &#x1f31f; 核心功能 ✅ 基于 DDD 领域驱动设计的模块化架构✅ 注解…

作者头像 李华
网站建设 2026/4/17 16:56:21

金融风控新工具:基于腾讯混元OCR的身份证与银行卡信息提取

金融风控新工具&#xff1a;基于腾讯混元OCR的身份证与银行卡信息提取 在银行柜台前排队数小时&#xff0c;只为核实一张身份证&#xff1f;线上贷款申请提交后&#xff0c;等上半天却被告知“资料不全”&#xff1f;这些看似琐碎的流程瓶颈&#xff0c;背后其实是金融风控中最…

作者头像 李华
网站建设 2026/4/16 8:58:29

从入门到精通:C# 12顶级语句如何重塑现代.NET项目开发?

第一章&#xff1a;C# 12顶级语句的演进与核心价值C# 12 对顶级语句&#xff08;Top-Level Statements&#xff09;进行了进一步优化&#xff0c;使其在简化程序入口点方面更加成熟和实用。开发者无需再编写冗长的类和方法结构即可直接运行代码&#xff0c;特别适用于小型脚本、…

作者头像 李华
网站建设 2026/4/23 14:50:57

C# 12主构造函数+只读属性=完美封装?真相令人震惊!

第一章&#xff1a;C# 12主构造函数与只读属性的完美封装之谜 在 C# 12 中&#xff0c;主构造函数&#xff08;Primary Constructors&#xff09;的引入极大简化了类和结构体的初始化逻辑&#xff0c;尤其在与只读属性结合使用时&#xff0c;展现出卓越的封装能力。这一特性不仅…

作者头像 李华