提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
一、为什么需要封装线程库?
在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(); // 获取实际线程ID
self->_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; // 线程ID
pid_t _lwpid; // 轻量级进程ID
std::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;
}