1. Thread.hpp
#pragma once
#include <iostream>
#include <string>
#include <functional>
template<class T>
using func_t = std::function<void(T)>;
template<class T>
class Thread
{
public:
Thread(func_t<T> func, const std::string &threadname, T data)
:_tid(0), _threadname(threadname), _isrunning(false), _func(func), _data(data)
{}
static void *ThreadRoutine(void* args)
{
Thread *ts = static_cast<Thread *>(args);
ts->_func(ts->_data);
return nullptr;
}
bool Start()
{
int n = pthread_create(&_tid, nullptr, ThreadRoutine, this);
if(n == 0)
{
_isrunning = true;
return true;
}
else return false;
}
bool Join()
{
if(!_isrunning) return false;
int n = pthread_join(_tid, nullptr);
if(n == 0)
{
_isrunning = false;
return true;
}
return false;
}
bool IsRunning()
{
return _isrunning;
}
~Thread()
{}
private:
pthread_t _tid;
std::string _threadname;
bool _isrunning;
func_t<T> _func;
T _data;
};
- 需要格外注意一点,
ThreadRoutine
必须写成静态成员函数,因为普通成员函数会默认携带this
指针,这样就会有两个参数,一个this
,一个void* args
。而pthread_create
函数只接受只有一个参数void* args
的函数。
- 将
ThreadRoutine
写成静态成员函数后,它将无法通过隐含的this
指针访问到成员变量_func
。为了解决这个问题,可以将this
指针显示的传给pthread_create
函数的void* args
参数,这样ThreadRoutine
就拿到了this
指针,之后再做一些变换就可以访问到_func
了。
2. main.cc
#include <iostream>
#include <unistd.h>
#include <string>
#include "Thread.hpp"
std::string GetThreadName()
{
static int number = 1;
char name[64];
snprintf(name, sizeof(name), "Thread-%d", number++);
return name;
}
void Print(int num)
{
while(num--)
{
std::cout << "hello world" << std::endl;
sleep(1);
}
}
int main()
{
Thread<int> t(Print, GetThreadName(), 5);
std::cout << "is thread running?" << t.IsRunning() << std::endl;
t.Start();
std::cout << "is thread running?" << t.IsRunning() << std::endl;
t.Join();
std::cout << "Join done" << std::endl;
return 0;
}