Linux-线程封装

发布时间:2026/10/31 11:10:19
Linux-线程封装 摘要本文基于 pthread 从零封装一个 C 线程类 Thread逐步解决类内成员函数作为线程入口导致的编译报错问题通过 static 入口函数配合 this 指针传参完成回调绑定同时引入 _isrunning 标志位控制线程启动状态与 Join 的合法性并借助 syscall(SYS_gettid) 获取线程底层 LWP最终给出可直接复用的完整线程封装代码。我们需要写一个线程封装实现我们自己的一个线程类才能更加深入了解线程#ifndef __THREAD_HPP__ #define __THREAD_HPP__ #includeiostream #includevector #includepthread.h #includestring #includefunctional using func_t std::functionvoid(); //默认名字 const std::string threadnamedefault None-Name; //线程类 class Thread { public: Thread(func_t func,const std::string name threadnamedefault) :_name(name) ,_func(func) {} void* start_routine(void* args) { } void Start() { int n pthread_create(_tid,nullptr,start_routine,nullptr); } void Join() { int n pthread_join(_tid,nullptr); if(n 0) { //等待线程成功 std::cout 等待线程成功 std::endl; } } ~Thread(){} private: pthread_t _tid;//线程ID pthread_t _lwpid;//底层的LWP std::string _name;//线程名字 func_t _func;//线程执行的方法 }; #endif但是这样写会出现波浪号这是因为我们的start_routine是类内函数需要使用this指针可以这样写void* start_routine(Thread* this,void* args)我们也可以这样写static void* start_routine(void* args)因为我们的这个类并没有被实例化所以这个会报错我们也可以把它放到类外面去不过那样比较麻烦因此此时我们就可以传递参数了int n pthread_create(_tid,nullptr,start_routine,this);此时的start_routine就可以改为我们还需要一个标志位来代表线程是否启动bool _isrunning;//线程是否被启动只有当start_routine函数即该类执行的方法开始了才会启动此外如果线程没有启动那么就不能Join//检测线程结束并且回收 void Join() { if(!_isrunning) return; int n pthread_join(_tid,nullptr); if(n 0) { //等待线程成功 std::cout 等待线程成功 std::endl; } }我们现在可以获取线程的LWP需要添加#includeunistd.h #includesys/syscall.h #define get_lwp_id() syscall(SYS_gettid)其实现在这结构已经能够做到基本的操作了主要代码#ifndef __THREAD_HPP__ #define __THREAD_HPP__ #includeiostream #includevector #includepthread.h #includeunistd.h #includestring #includefunctional #includesys/syscall.h #define get_lwp_id() syscall(SYS_gettid) using func_t std::functionvoid(); //默认名字 const std::string threadnamedefault None-Name; //线程类 class Thread { public: Thread(func_t func,const std::string name threadnamedefault) :_name(name) ,_func(func) ,_isrunning(false) { //创建线程成功 std::cout 创建线程成功 std::endl; } static void* start_routine(void* args) { Thread* self static_castThread*(args);//用于接受外部传入的函数参数 //将线程启动 self-_isrunning true; //获取线程ID self-_lwpid get_lwp_id(); //回调我们自己的方法 self-_func(); //返回 pthread_exit((void*)0); } void Start() { int n pthread_create(_tid,nullptr,start_routine,this); //启动线程成功 if(n 0) std::cout 启动线程成功 std::endl; } //检测线程结束并且回收 void Join() { if(!_isrunning) return; int n pthread_join(_tid,nullptr); if(n 0) { //等待线程成功 std::cout 等待线程成功 std::endl; } } ~Thread(){} private: bool _isrunning;//线程是否被启动 pthread_t _tid;//线程ID pthread_t _lwpid;//底层的LWP std::string _name;//线程名字 func_t _func;//线程执行的方法 }; #endif或者Gitee:fthread · 谭旦0000/test_for_csdn - 码云 - 开源中国

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询