目录
一、整体框架
#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <pthread.h>
typedef std::function<void *(void *)> func_t;
const int num = 1024;
class Thread
{
private:
static void *start_routine(void *args)
{
Thread *_this = static_cast<Thread *>(args);
return _this->callback();
}
void *callback() { return _func(_args); }
public:
Thread();
void start(func_t func, void *args = nullptr);
void join();
std::string threadname() { return _name; }
private:
std::string _name; // 线程名称
pthread_t _tid; // 线程id
func_t _func; // 线程要执行的函数
void *_args; // 线程要执行的函数 的参数
static int _threadnum; // 线程编号
};
int Thread::_threadnum = 1;
对static void *start_routine(void *args)函数的解释
① 解释功能:他是线程要执行的start_routine函数【参数void*,返回值void*】
② 为什么要有static?
类内函数有一个默认参数this指针,这就与start_routine函数的参数不匹配了
static修饰的类内函数没有this指针,所以加static就让start_routine函数的参数符合要求了
③ 又引出了一个新的问题:static函数没有this,那他就访问不到类内的回调函数 func_t _func;
首先创建 void *callback() { return _func(_args); } 函数,用callback函数来访问类内回调函数
在给start_routine传参的时候,给他传this指针,通过this找到callback就可以访问回调函数了
总结:实际上真正执行线程的函数是callback,而start_routine只是为了传递this指针
二、具体实现
1.Thread()
Thread()构造函数:给线程起名字
Thread()
{
char namebuffer[num];
snprintf(namebuffer, sizeof(namebuffer), "thread-%d", _threadnum++);
_name = namebuffer;
}
2.void start()
start()启动函数:参数是线程要执行的函数及其参数,负责创建线程
void start(func_t func, void *args = nullptr)
{
_func = func; // 回调函数
_args = args; // 回调函数的参数
int n = pthread_create(&_tid, nullptr, start_routine, (void *)this);
assert(n == 0);
(void)n;
}
3.void join()
join()函数负责线程等待
void join()
{
int n = pthread_join(_tid, nullptr);
assert(n == 0);
(void)n;
}
三、使用方法
#include "testthread.hpp"
#include <unistd.h>
#include <string>
void *run(void *args)
{
std::string message = *static_cast<std::string *> (args);
while (true)
{
std::cout << message << std::endl;
sleep(1);
}
return nullptr;
}
int main()
{
Thread t1;
Thread t2;
std::string msg1 = "thread 1 run"; // 使用 std::string 对象
std::string msg2 = "thread 2 run";
t1.start(run, (void *)&msg1); // 传递 msg1 的地址
t2.start(run, (void *)&msg2); // 传递 msg2 的地址
t1.join();
t2.join();
return 0;
}