news 2026/6/9 19:39:07

【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/6/9 16:16:37

如何用一行代码替代循环合并?C#集合表达式+展开运算符的终极答案

第一章&#xff1a;C#集合表达式与展开运算符的终极答案C# 12 引入了集合表达式和展开运算符&#xff0c;极大增强了集合初始化和操作的表达能力。这些特性不仅简化了代码书写&#xff0c;还提升了性能与可读性。集合表达式的语法革新 集合表达式允许使用简洁的方括号语法创建和…

作者头像 李华
网站建设 2026/6/9 16:16:59

LUT调色包与HunyuanOCR联合用于古籍修复数字化项目

LUT调色包与HunyuanOCR联合用于古籍修复数字化项目 在图书馆和档案馆的深处&#xff0c;泛黄脆弱的古籍静静躺在恒温恒湿柜中。一页页斑驳的纸张上&#xff0c;墨迹或晕染、或褪去&#xff0c;有些字形已模糊难辨——这不仅是时间留下的痕迹&#xff0c;更是数字化进程中必须跨…

作者头像 李华
网站建设 2026/6/9 16:16:59

为什么你的Lambda不能用默认参数?揭开C#编译器背后的限制真相

第一章&#xff1a;为什么Lambda表达式不支持默认参数Lambda表达式作为现代编程语言中函数式编程的重要特性&#xff0c;被广泛用于简化匿名函数的定义。然而&#xff0c;许多开发者在使用过程中会发现一个共性限制&#xff1a;主流语言中的Lambda表达式通常不支持默认参数。这…

作者头像 李华
网站建设 2026/6/9 16:16:37

清华镜像站HTTPS证书配置正确才能拉取HunyuanOCR

清华镜像站HTTPS证书配置正确才能拉取HunyuanOCR 在高校实验室部署一个轻量级OCR模型时&#xff0c;你是否遇到过这样的场景&#xff1a;明明网络通畅&#xff0c;ping 得通清华镜像站&#xff0c;但 pip install 或 docker pull 就是卡住不动&#xff0c;最后抛出一串红色错误…

作者头像 李华
网站建设 2026/6/9 17:23:12

HTML video元素捕获帧图像送入HunyuanOCR识别字幕

HTML video元素捕获帧图像送入HunyuanOCR识别字幕 在教育视频自动转讲义、短视频内容审核、多语言字幕实时翻译等场景中&#xff0c;一个共通的技术需求浮出水面&#xff1a;如何从正在播放的视频里&#xff0c;精准提取出画面中的文字信息&#xff1f;尤其是当这些文字以动态字…

作者头像 李华
网站建设 2026/6/9 17:20:54

为什么顶级团队都在用C# 12主构造函数实现不可变类型?

第一章&#xff1a;C# 12主构造函数与不可变类型的崛起C# 12 引入了主构造函数&#xff08;Primary Constructors&#xff09;这一重要特性&#xff0c;显著简化了类和结构体的初始化逻辑&#xff0c;尤其在构建不可变类型时展现出强大优势。该特性允许开发者在类声明级别直接定…

作者头像 李华