teleport/common/libex/include/ex/ex_thread.h

234 lines
4.0 KiB
C
Raw Normal View History

#ifndef __EX_THREAD_H__
#define __EX_THREAD_H__
2017-09-16 17:04:42 +00:00
#include "ex_str.h"
2016-12-06 17:05:56 +00:00
#include <list>
#ifdef EX_OS_WIN32
# include <process.h>
typedef HANDLE EX_THREAD_HANDLE;
2020-11-02 16:57:26 +00:00
# define EX_THREAD_NULL NULL
2016-12-06 17:05:56 +00:00
#else
# include <pthread.h>
# include <sys/time.h>
typedef pthread_t EX_THREAD_HANDLE;
2020-11-02 16:57:26 +00:00
# if defined(EX_OS_LINUX)
# define EX_THREAD_NULL 0
# elif defined(EX_OS_MACOS)
# define EX_THREAD_NULL nullptr
# endif
2016-12-06 17:05:56 +00:00
#endif
class ExThreadBase
2016-12-06 17:05:56 +00:00
{
public:
explicit ExThreadBase(const char* thread_name);
virtual ~ExThreadBase();
2016-12-06 17:05:56 +00:00
bool is_running() const
{
return m_is_running;
}
2016-12-06 17:05:56 +00:00
// 创建并启动线程执行被重载了的run()函数)
bool start();
// 结束线程等待wait_timeout_ms毫秒如果wait_timeout_ms为0则无限等待
bool stop();
// 直接结束线程(强杀,不建议使用)
bool terminate();
2016-12-06 17:05:56 +00:00
protected:
// main loop of this thread.
virtual void _thread_loop() = 0;
// called by another thread when thread ready to stop.
virtual void _on_stop()
{
};
// called inside thread when thread fully stopped.
virtual void _on_stopped()
{
};
2016-12-06 17:05:56 +00:00
#ifdef EX_OS_WIN32
static unsigned int WINAPI _thread_func(LPVOID lpParam);
2016-12-06 17:05:56 +00:00
#else
static void* _thread_func(void* pParam);
2016-12-06 17:05:56 +00:00
#endif
protected:
ex_astr m_thread_name;
EX_THREAD_HANDLE m_handle;
bool m_is_running;
bool m_need_stop;
2016-12-06 17:05:56 +00:00
};
// 线程锁(进程内使用)
class ExThreadLock
2016-12-06 17:05:56 +00:00
{
public:
ExThreadLock();
virtual ~ExThreadLock();
2016-12-06 17:05:56 +00:00
void lock();
void unlock();
2016-12-06 17:05:56 +00:00
private:
#ifdef EX_OS_WIN32
CRITICAL_SECTION m_locker;
2016-12-06 17:05:56 +00:00
#else
pthread_mutex_t m_locker;
2016-12-06 17:05:56 +00:00
#endif
};
// 线程锁辅助类
class ExThreadSmartLock
2016-12-06 17:05:56 +00:00
{
public:
explicit ExThreadSmartLock(ExThreadLock& lock) :
m_lock(lock)
{
m_lock.lock();
}
~ExThreadSmartLock()
{
m_lock.unlock();
}
2016-12-06 17:05:56 +00:00
private:
ExThreadLock& m_lock;
2016-12-06 17:05:56 +00:00
};
typedef std::list<ExThreadBase*> ex_threads;
2016-12-06 17:05:56 +00:00
class ExThreadManager
2016-12-06 17:05:56 +00:00
{
friend class ExThreadBase;
2016-12-06 17:05:56 +00:00
public:
ExThreadManager();
virtual ~ExThreadManager();
void stop_all();
//private:
void add(ExThreadBase* tb);
void remove(ExThreadBase* tb);
2016-12-06 17:05:56 +00:00
private:
ExThreadLock m_lock;
ex_threads m_threads;
};
// Event
class ExEventHelper;
class ExEvent
{
friend class ExEventHelper;
2016-12-06 17:05:56 +00:00
public:
ExEvent()
{
#ifdef EX_OS_WIN32
#else
pthread_mutex_init(&m_mutex, nullptr);
pthread_cond_init(&m_cond, nullptr);
#endif
}
~ExEvent()
{
#ifdef EX_OS_WIN32
#else
pthread_mutex_destroy(&m_mutex);
pthread_cond_destroy(&m_cond);
#endif
}
void wait()
{
#ifdef EX_OS_WIN32
#else
pthread_cond_wait(&m_cond, &m_mutex);
#endif
}
void wait_timeout_ms(int timeout_ms)
{
#ifdef EX_OS_WIN32
#else
// timeval.tv_usec ==== ms
// timespec.tv_nsec === nano-second
2021-07-12 08:22:55 +00:00
struct timeval now = {0};
struct timespec out_time = {0};
gettimeofday(&now, nullptr);
uint64_t abs_time_ms = now.tv_sec * 1000ll + now.tv_usec + timeout_ms;
2021-07-12 08:22:55 +00:00
out_time.tv_sec = abs_time_ms / 1000ll;
out_time.tv_nsec = (long)((abs_time_ms % 1000ll) * 1000ll);
pthread_cond_timedwait(&m_cond, &m_mutex, &out_time);
#endif
}
void signal()
{
#ifdef EX_OS_WIN32
#else
pthread_cond_signal(&m_cond);
#endif
}
2016-12-06 17:05:56 +00:00
private:
#ifdef EX_OS_WIN32
#else
pthread_mutex_t m_mutex;
2021-07-12 08:22:55 +00:00
pthread_cond_t m_cond;
#endif
2016-12-06 17:05:56 +00:00
};
class ExEventHelper
{
public:
explicit ExEventHelper(ExEvent& event) :
2021-07-12 08:22:55 +00:00
m_event(event)
{
#ifdef EX_OS_WIN32
#else
pthread_mutex_lock(&m_event.m_mutex);
#endif
}
~ExEventHelper()
{
#ifdef EX_OS_WIN32
#else
pthread_mutex_unlock(&m_event.m_mutex);
#endif
}
private:
ExEvent& m_event;
};
2016-12-06 17:05:56 +00:00
// 原子操作
int ex_atomic_add(volatile int* pt, int t);
2021-07-12 08:22:55 +00:00
int ex_atomic_inc(volatile int* pt);
2021-07-12 08:22:55 +00:00
int ex_atomic_dec(volatile int* pt);
2016-12-06 17:05:56 +00:00
// 线程相关操作
uint64_t ex_get_thread_id();
#endif // __EX_THREAD_H__