当前位置: 首页 > news >正文

【Linux】线程封装

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

一、为什么需要封装线程库?

pthread的痛点:

封装带来的好处:

二、线程封装核心代码解析

1. 头文件定义(Thread.hpp)

三、关键技术点详解

1. std::function的魅力

2. 静态成员函数的巧妙使用

3. 获取真实的线程ID

四、使用示例和测试代码

测试代码(main.cpp)


一、为什么需要封装线程库?

在Linux C++开发中,我们经常需要使用多线程。原生的pthread接口虽然强大,但存在一些问题:

pthread的痛点:

  • 🔧 C风格接口:函数指针和void*参数不够类型安全

  • 📝 冗长的代码:需要手动管理线程创建、连接、销毁

  • 🚫 易出错:容易忘记检查返回值,导致难以调试的问题

  • 🔄 缺乏RAII:资源管理需要手动处理

封装带来的好处:

  • 🎯 类型安全:使用std::function代替函数指针

  • 🚀 简洁易用:几行代码完成线程管理

  • 🛡️ 异常安全:利用RAII自动管理资源

  • 📦 可扩展性:方便添加新功能(如线程池)

二、线程封装核心代码解析

1. 头文件定义(Thread.hpp)

 

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <functional>
#include <sys/syscall.h>// 获取轻量级进程ID(线程ID)
#define get_lwp_id() syscall(SYS_gettid)// 定义函数类型别名
using func_t = std::function<void()>;class Thread
{
public:// 构造函数:接收线程函数和线程名Thread(func_t func, const std::string &name): _name(name), _func(func), _isrunning(false){}// 静态成员函数:线程启动例程static void *start_routine(void *args){Thread *self = static_cast<Thread *>(args);self->_isrunning = true;self->_lwpid = get_lwp_id();  // 获取实际线程IDself->_func();                // 执行用户函数pthread_exit((void *)0);      // 线程退出}// 启动线程void Start(){int n = pthread_create(&_tid, nullptr, start_routine, this);if (n == 0){std::cout << "线程" << _name << "创建成功" << std::endl;}}// 等待线程结束void Join(){if (!_isrunning) return;int n = pthread_join(_tid, nullptr);if (n == 0){std::cout << "线程" << _name << "回收成功" << std::endl;}}~Thread() {}private:bool _isrunning;        // 线程运行状态pthread_t _tid;         // 线程IDpid_t _lwpid;           // 轻量级进程IDstd::string _name;      // 线程名称func_t _func;           // 线程执行函数
};

三、关键技术点详解

1. std::function的魅力

传统pthread的问题:

 // C风格:需要静态函数和void*参数
void* thread_func(void* arg) {// 需要类型转换int* data = (int*)arg;// ...
}

我们的解决方案:

 

// C++11风格:类型安全的函数对象
using func_t = std::function<void()>;// 可以接收任何可调用对象:
// 1. 普通函数
// 2. Lambda表达式  
// 3. 函数对象
// 4. std::bind表达式

2. 静态成员函数的巧妙使用

为什么需要静态函数?
pthread_create要求C风格的函数指针,但普通成员函数有隐式的this参数。

解决方案:

 

static void *start_routine(void *args) {Thread *self = static_cast<Thread *>(args);  // 转换回对象指针self->_func();  // 调用真正的线程函数
}

3. 获取真实的线程ID

 

#define get_lwp_id() syscall(SYS_gettid)// 为什么需要这个?
// - pthread_t是进程内标识,在不同进程中可能重复
// - 通过系统调用获取的LWP ID是系统范围内唯一的
// - 便于调试和系统监控

四、使用示例和测试代码

测试代码(main.cpp)

 

#include "Thread.hpp"
#include <iostream>
#include <vector>// 测试函数
void Test()
{int cnt = 3;while (cnt--){std::cout << "线程" << get_lwp_id() << "正在运行..." << std::endl;sleep(1);}
}// Lambda表达式测试
auto lambda_test = []() {std::cout << "Lambda线程运行中" << std::endl;sleep(2);
};int main()
{std::cout << "=== 单线程测试 ===" << std::endl;Thread t1(Test, "single-thread");t1.Start();t1.Join();std::cout << "\n=== 多线程测试 ===" << std::endl;std::vector<Thread> threads;// 创建3个线程for (int i = 0; i < 3; i++){std::string name = "thread-";name += std::to_string(i + 1);threads.emplace_back(Test, name);}// 启动所有线程for (auto &thread : threads){thread.Start();}// 等待所有线程结束for (auto &thread : threads){thread.Join();}std::cout << "\n=== Lambda测试 ===" << std::endl;Thread t2(lambda_test, "lambda-thread");t2.Start();t2.Join();return 0;
}

http://www.dtcms.com/a/364926.html

相关文章:

  • 组长跟我说,她招人看重的是数据分析能力
  • 基于数据挖掘的当代不孕症医案证治规律研究
  • 从0 死磕全栈第3天:React Router (Vite + React + TS 版):构建小时站实战指南
  • 什么是 Java 的反射机制?它有什么优缺点?
  • 20250903的学习笔记
  • 百度发布Comate AI IDE,我要把Cursor卸载了!
  • 机器学习从入门到精通 - 逻辑回归为什么是分类之王?深入决策边界与概率校准
  • 《嵌入式硬件(一):裸机概念与80c51单片机基础》
  • “十五五”国家科技创新规划-建议
  • 百度智能云「智能集锦」自动生成短剧解说,三步实现专业级素材生产
  • Netty + WebSocket:搭建快速且稳定的双向通信通道
  • word文档中从某一页开始页码全是1
  • Wpf程序屏幕居中问题修复全记录
  • 39.Ansible: 包含与导入
  • FastVLM:高效视觉编码助力视觉语言模型突破高分辨率效率瓶颈
  • 独家|字节Seed部门增发百万期权,大模型战线开启“锁人”模式
  • 【golang长途旅行第37站】Redis连接池
  • MMD动画(一)模型、动作、音乐导入
  • 【大前端】React 父子组件通信、子父通信、以及兄弟(同级)组件通信
  • 科技赋能田园:数字化解决方案开启智慧农业新篇章
  • centos9 docker启动不起来,docker启动发生堵塞问题!
  • 【明道云】[工作表控件5] 手机控件的格式化处理
  • 【机器学习】实战:市场增长点分析挖掘项目
  • SyncBack 备份同步软件: 使用增量备份, 节省网络传输及存储成本
  • 【NVIDIA B200】2.all_reduce_perf NVIDIA B200 8-GPU 系统 All-Reduce 性能深度解析
  • 力扣115:不同的子序列
  • 热烈庆祝 | 一二三物联网携这款产品入选2025年度山东省首台(套)技术装备生产企业及产品名单
  • Day20 JavaScript 进阶核心:IIFE、代码规范、调试与对象模型
  • AI优化SEO关键词策略指南
  • 时序数据库选型指南:Apache IoTDB快速部署与实战应用