头文件duye_thread.h
/************************************************************************************
**
* @copyright (c) 2013-2100, Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file duye_thread.h
* @version
* @brief
* @autho duye
* @date 2013-11-26
* @note
*
* 2. 2014-01-12 duye Add comments
* 1. 2013-11-26 Created this file
*
*/
#pragma once
#include <pthread.h>
#include <duye_type.h>
namespace duye {
/**
* @brief thread state
*/
typedef enum {
/**
* @brief running state
*/
THR_STATE_RUN = 0,
/**
* @brief stoped state
*/
THR_STATE_STOP,
/**
* @brief exit state
*/
THR_STATE_EXIT
} ThreadState;
/**
* @brief the pointer of thread enter
*/
typedef void* (*ThreadFunPoint)(void*);
/**
* @brief be inherited ty user
*/
class Runnable {
public:
virtual ~Runnable() {}
/**
* @brief user thread entry function
* @return true/false
* @note
*/
virtual bool run() = 0;
};
/**
* @brief POSIX thread wrapper
*/
class Thread {
public:
/**
* @brief constructor
* @param [in] target : user run target object
* @param [in] autoRel : whether support automatic release, default is yes
* @note
*/
explicit Thread(const bool autoRel = true);
explicit Thread(Runnable* target, const bool autoRel = true);
~Thread();
/**
* @brief startup thread
* @return true/false
* @note
*/
bool start();
bool start(Runnable* target, const bool autoRel = true);
/**
* @brief join thread
*/
bool join();
/**
* @brief exit thread
*/
void exit();
/**
* @brief get thread ID
* @return thread ID
* @note
*/
uint64 threadId() const;
private:
Thread(const Thread&);
void operator=(const Thread&);
static void* enterPoint(void* argument);
private:
// thread ID
pthread_t m_threadId;
// indicate whether is detached with main thread default is detached
bool m_autoRel;
// user thread object
Runnable* m_runnable;
};
/**
* @brief thread base class, be inherited by user
*/
class ThreadTask : public Runnable {
public:
/**
* @brief constructor
* @para [in] autoRel : whether is detached with main thread, default is detached
* @note
*/
explicit ThreadTask(const bool autoRel = true);
virtual ~ThreadTask();
/**
* @brief startup thread
* @param [in] autoRel : whether is detached from main thread, default is detached
* @return true/false
* @note
*/
bool startTask(const bool autoRel = true);
/**
* @brief join
* @return true/false
*/
bool join();
/**
* @brief get thread ID
* @return thread ID
*/
uint64 threadId() const;
/**
* @brief thread entry function
* @return true/false
* @note
*/
virtual bool run() = 0;
private:
// brief : prevate copying
ThreadTask(const ThreadTask&);
void operator=(const ThreadTask&);
private:
Thread m_thread;
// whether is detached with main thread, default is ture,
// indicate detached with main thread
bool m_autoRel;
};
/**
* @brief POSIX thread static API used outside
*/
class ThreadUtil {
public:
/**
* @brief create thread
* @param [in] entry : thread entry fucntion pointer
* @param [in] argument : user data
* @param [in] autoRel : whether support automatic release, default is yes
* @return thread ID / -1
* @note
*/
static int32 createThread(void* entry, void* argument, const bool autoRel = true);
};
}
cpp文件duye_thread.cpp
/************************************************************************************
**
* @copyright (c) 2013-2100, Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file duye_thread.cpp
* @version
* @brief
* @author
* @date 2013-11-26
* @note
*
* 1. 2013-11-26 Created this file
*
*/
#include <stdio.h>
#include <duye_thread.h>
namespace duye {
Thread::Thread(const bool autoRel)
: m_threadId(0)
, m_autoRel(autoRel)
, m_runnable(NULL) {}
Thread::Thread(Runnable* runnable, const bool autoRel)
: m_threadId(0)
, m_autoRel(autoRel)
, m_runnable(runnable) {}
Thread::~Thread() {}
bool Thread::start() {
pthread_attr_t* attributes = NULL;
bool ret = pthread_create(&m_threadId, attributes, enterPoint, m_runnable);
if (ret != 0) {
return false;
}
if (m_autoRel) {
pthread_detach(m_threadId);
}
return true;
}
bool Thread::start(Runnable* target, const bool autoRel) {
m_runnable = target;
m_autoRel = autoRel;
return start();
}
bool Thread::join() {
return pthread_join(m_threadId, NULL) == 0 ? true : false;
}
void Thread::exit() {
pthread_exit(NULL);
}
uint64 Thread::threadId() const {
return (uint64)pthread_self();
}
void* Thread::enterPoint(void* argument) {
Runnable* runnable = static_cast<Runnable*>(argument);
runnable->run();
return NULL;
}
ThreadTask::ThreadTask(const bool autoRel) : m_autoRel(autoRel) {}
ThreadTask::~ThreadTask() {}
bool ThreadTask::startTask(const bool autoRel) {
return m_thread.start(this, autoRel);
}
bool ThreadTask::join() {
return m_thread.join();
}
uint64 ThreadTask::threadId() const {
return m_thread.threadId();
}
int32 ThreadUtil::createThread(void* entry, void* argument, const bool autoRel) {
pthread_attr_t* attributes = NULL;
pthread_t threadId = -1;
int32 ret = pthread_create(&threadId, attributes, (ThreadFunPoint)entry, argument);
if (ret != 0) {
return (int32)threadId;
}
if (autoRel) {
pthread_detach(threadId);
}
return (int32)threadId;
}
}
开源地址:https://gitee.com/DuyeOpen/Venus