代码仓库地址:https://gitee.com/tgwTTT/linux-learning-dai/tree/master/TestThread3
学习本文建议参考上一篇文章:http://www.tgwttt.xyz/?p=289
现代C++开发中,线程的使用越来越普遍。虽然C++11及以后标准提供了std::thread,但在一些项目中,仍然需要直接使用POSIX线程(pthread)进行更细致的控制。本文将介绍一个基于pthread的线程封装类,也是对POSIX线程库的基本应用巩固
1. 设计目标
我们希望实现一个模板化的线程类,能够:
- 支持传递任意类型的数据给线程函数
- 支持线程分离(detach)与等待(join)
- 支持线程的启动与停止
- 便于扩展和使用
2. 类定义与成员变量
首先来看类的基本结构。我们使用模板类,支持传递任意类型的数据:
namespace ThreadModlue {
template
class Thread {
using func_t = std::function;
// ...成员变量定义...
};
}
主要成员变量包括:
pthread_t tid:线程ID
std::string _name:线程名称
bool _isdetach:是否分离
bool isrunning:是否正在运行
void* res:线程返回值
func_t _func:线程执行的回调函数
T _data:传递给线程的数据
3. 构造函数与命名
每个线程对象都会自动分配一个唯一名称,便于调试和管理:
Thread(func_t func, const T& t)
: tid(0), _isdetach(false), isrunning(false), _func(func), _data(t) {
_name = "Thread" + std::to_string(number++);
}
4. 线程启动与执行
线程的启动通过Start()方法实现,内部调用pthread_create:
void Start() {
if (isrunning) return;
int n = pthread_create(&tid, nullptr, Routine, this);
if (n > 0) {
std::cerr << "Thread create failed " << strerror(n) << std::endl;
return;
}
EnableRunning();
}
线程的实际执行逻辑在Routine静态方法中完成:
static void* Routine(void* args) {
Thread* self = static_cast*>(args);
if (self->_isdetach)
self->Detach();
self->_func(self->_data); // 回调函数
return nullptr;
}
5. 分离与等待
线程可以选择分离(detach)或等待(join):
- 分离:线程运行结束后自动释放资源,不能再通过
join等待 - 等待:主线程可以通过
join等待子线程结束
void Detach() {
if (!_isdetach) {
if (isrunning)
pthread_detach(tid);
EnableDetach();
}
}
void Join() {
if (_isdetach) {
std::cerr << "Thread is detached, can't join" << std::endl;
return;
}
int n = pthread_join(tid, &res);
if (n > 0) {
std::cerr << "Thread join failed " << strerror(n) << std::endl;
}
}
6. 停止线程
通过Stop()方法可以尝试取消线程:
void Stop() {
if (isrunning) {
int n = pthread_cancel(tid);
if (n > 0) {
std::cerr << "Thread cancel failed " << strerror(n) << std::endl;
} else {
isrunning = false;
std::cout << _name << " stopped" << std::endl;
}
}
}
今天的更新就到这里,如有错误欢迎评论区指出
评论
还没有任何评论,你来说两句吧!