封装pthread线程,将外部函数丢给封装函数以创建线程后,外部不需再管理线程,当线程运行结束后自动释放,非线程池。
#pragma once
#include <string.h>
#include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <cerrno>
#define UNUSED(x) (void)x
typedef unsigned long _size_t;
#define THREAD_PROC
typedef _size_t(THREAD_PROC *thread_proc_t)(void *);
#define CLASS_THREAD(c, x) utils_thread::Thread::ThreadCreateObjectFunctor<c, &c::x>(this)
namespace utils_thread
{
class Thread
{
public:
template <class CLASS, int (CLASS::*PROC)(void)>
static Thread ThreadCreateObjectFunctor(CLASS *pthis)
{
return createThread(createThreadAux<CLASS, PROC>, pthis);
}
template <class CLASS, int (CLASS::*PROC)(void)>
static _size_t THREAD_PROC createThreadAux(void *param)
{
return (static_cast<CLASS *>(param)->*PROC)();
}
static Thread createThread(thread_proc_t proc, void *param = NULL)
{
Thread thread_(proc, param);
assert(sizeof(thread_._handle) >= sizeof(pthread_t));
int ret = pthread_create((pthread_t *)&thread_._handle,
NULL, (void *(*)(void *))proc,
param);
if (ret != 0)
{
thread_._handle = 0;
// printf("[my thread] Fail to create thread!\tError[%s]", strerror(ret));
}
return thread_;
}
public:
explicit Thread() : _param(NULL), _func(NULL), _handle(0), _finished(false) {}
virtual ~Thread()
{
// 在析构函数中检测并释放线程
join();
}
_size_t getHandle()
{
return _handle;
}
int terminate()
{
if (!_handle)
{
return 0;
}
return pthread_cancel((pthread_t)_handle);
}
void *getParam()
{
return _param;
}
int join(unsigned long timeout = -1)
{
if (!_handle)
return 0;
UNUSED(timeout);
// 等待线程执行完毕
while (!_finished)
{
usleep(1000); // 等待1毫秒
}
int s = pthread_join((pthread_t)_handle, NULL);
if (s != 0)
{
// printf("[my thread] An error occurred while thread[0x%X] cancelled!", _handle);
return s;
}
// printf("[my thread] Thread [0x%X] has been canceled", _handle);
_handle = 0;
return 0;
}
static void needExit()
{
pthread_testcancel();
}
bool operator==(const Thread &right)
{
return this->_handle == right._handle;
}
protected:
explicit Thread(thread_proc_t proc, void *param) : _param(param), _func(proc),
_handle(0), _finished(false) {}
void *_param;
thread_proc_t _func;
_size_t _handle;
bool _finished;
template <class CLASS, int (CLASS::*PROC)(void)>
friend _size_t THREAD_PROC createThreadAux(void *param);
};
template <class CLASS, int (CLASS::*PROC)(void)>
_size_t THREAD_PROC createThreadAux(void *param)
{
CLASS *pthis = static_cast<CLASS *>(param);
_size_t result = (pthis->*PROC)();
Thread *thread = static_cast<Thread *>(param);
thread->_finished = true;
return result;
}
}
class MyThread : public utils_thread::Thread
{
public:
MyThread() {}
int run()
{
for (int i = 0; i < 5; ++i)
{
std::cout << "Thread is running..." << std::endl;
sleep(1);
}
return 0;
}
};
int main()
{
MyThread thread;
thread.createThreadAux<MyThread, &MyThread::run>(&thread);
return 0;
}