同步事件,信号量,互斥,临界区,线程,线程池C++实现(win32,linux)

这是一个C++库,用于在Win32和Linux环境下实现多线程同步,包括事件、信号量、互斥量、临界区、线程和线程池。通过类接口,提供了跨平台的同步对象操作,如上锁、等待、解锁等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
* @note		:同步事件/信号量/互斥/临界区/线程/线程池实现(win32/linux),不支持unicode
* @author	:Andy.Ro
* @email	:Qwuloo@qq.com
*/
#ifndef _XTHREAD_H_INCLUDE_
#define _XTHREAD_H_INCLUDE_

#ifdef WIN32
#include <Windows.h>
#include <process.h>
#else
// linux 手测参考:http://www.mkssoftware.com/docs
#include <sched.h>
#include <pthread.h>
#include <semaphore.h> // POSIX信号量(用户态)
//#include <sys/sem.h>   // SYSTEM V信号量(用户态)
#include <sys/types.h>
#include <unistd.h>
#define INFINITE 0xFFFFFFFF
#endif

#include "../Interface/xTypes.h"

#ifdef WIN32
typedef u32_t pthread_t;
#endif

namespace ESMT {

	class xSyncObject;
	class xEvent;					// 事件内核对象
	class xSemaphore;				// 信号量内核对象:linux 下仅实现了POSIX信号量
	class xMutex;					// 互斥内核对象
	class xSection;					// 临界区用户对象

	class xThread;					// 线程类
	class xThreadPool;				// 线程池

	//------------------------------------------------------------------------
	// xSyncObject 接口类
	//------------------------------------------------------------------------
	class xSyncObject
	{
	public:
		xSyncObject(void);
	
	public:
		// @note: 上锁
		virtual BOOL lock(void)							/*= 0;*/ { return FALSE; }
		
		// @note: 挂起调用线程,直到该内核对象被解锁
		// @param timeout <ulong_t> : 等待时间(毫秒)
		virtual BOOL wait(ulong_t timeout = INFINITE)	/*= 0;*/ { return FALSE; }
		
		// @note: 解锁
		virtual BOOL Unlock(void)						/*= 0;*/ { return FALSE; }
		
		// @note: 占用资源并进入访问
		virtual BOOL enter(void)						/*= 0;*/ { return FALSE; }

		// @note: 离开并释放占用资源
		virtual BOOL leave(void)						/*= 0;*/ { return FALSE; }

	public:
		virtual ~xSyncObject(void);
	};

	//------------------------------------------------------------------------
	// xEvent 多线程事件同步
	// linux 下参考:http://blog.youkuaiyun.com/ffilman/article/details/4871920
	//------------------------------------------------------------------------
	class xEvent : public xSyncObject
	{
#define		__signaled(e)		( (e).unlock() )
#define		__nonsignaled(e)	( (e).lock()   )
#define		__wait_signal(e,s)	( (e).wait(s)  )
	public:
		xEvent(
			BOOL initstate = FALSE, BOOL manualreset = FALSE
#ifdef WIN32
		   ,LPCTSTR lpName = NULL, LPSECURITY_ATTRIBUTES lpsa = NULL
#else
		   ,u32_t pshared = PTHREAD_PROCESS_PRIVATE
		   ,u32_t type = PTHREAD_MUTEX_TIMED_NP
#endif
			);
	public:
		// @note: 设置事件未受信(non-signaled)状态[人工重置(manual-reset)事件]
		/*inline*/ BOOL lock();
		
		// @note: 挂起调用线程,直到该事件对象受信(signaled)
		// @param timeout <ulong_t> : 等待时间(毫秒)
		/*inline*/ BOOL wait(ulong_t timeout = INFINITE);
		
		// @note: 设置事件受信(signaled)状态
		/*inline*/ BOOL unlock();
	
	public:
#ifdef WIN32
		HANDLE _event;
#else
#if 0
		typedef struct _cond_check_t
		{
			typedef BOOL (*cond_check_callback_func)(void * args);
			cond_check_callback_func _handler;
			void * _args;
		}cond_check_t;
		cond_check_t _cond_check;
#endif
		pthread_mutex_t _mutex;
		pthread_cond_t _cond;
		BOOL _manual_reset,_signaled;
#endif
	public:
		~xEvent(void);
	};

	//------------------------------------------------------------------------
	// xSemaphore,控制多线程对同一共享资源的并发访问
	// linux  下参考:http://blog.youkuaiyun.com/qinxiongxu/article/details/7830537
	//------------------------------------------------------------------------
	class xSemaphore : public xSyncObject
	{
	public:
		// @note:构造信号内核对象 
		// @param initvalue <ulong_t> : 初始可用访问资源计数
		// @param maxvalue  <ulong_t> : 允许最大访问资源计数,指定并发访问共享资源的最大线程数
		xSemaphore(ulong_t initvalue = 1
#ifdef WIN32
			,ulong_t maxvalue = 1
#endif
			,char const * name = NULL);
	
	public:	
		// @note: 占用资源并进入访问
		/*inline*/ BOOL enter();
		
		// @note: 离开并释放占用资源
		/*inline*/ BOOL leave();
	
	public:
#ifdef WIN32
		HANDLE _sem;
#else
		sem_t  _sem,*_p_sem;
		std::string _S_NAME;
#endif
	public:
		~xSemaphore(void);
	};

	//------------------------------------------------------------------------
	// xMutex 控制多线程对同一共享资源的互斥访问
	//------------------------------------------------------------------------
	class xMutex : public xSyncObject
	{
	public:
		xMutex(
#ifdef WIN32
			 LPCTSTR lpName = NULL, BOOL bInitOwner = FALSE, LPSECURITY_ATTRIBUTES lpsa = NULL
#else
			 u32_t pshared = PTHREAD_PROCESS_PRIVATE
			,u32_t type = PTHREAD_MUTEX_TIMED_NP
#endif
			);
	
	public:
		// @note: 占用资源并互斥访问
		/*inline*/ BOOL enter();
		
		// @note: 离开并释放占用资源
		/*inline*/ BOOL leave();
	
	public:
#ifdef WIN32
		HANDLE          _mutex;
#else
		pthread_mutex_t _mutex;
#endif
	public:
		~xMutex(void);
	};

	//------------------------------------------------------------------------
	// xSection,多线程访问临界资源
	//------------------------------------------------------------------------
	class xSection : public xSyncObject
	{
	public:
		xSection(
#ifdef WIN32
#else
			 u32_t pshared = PTHREAD_PROCESS_PRIVATE
			,u32_t type = PTHREAD_MUTEX_TIMED_NP
#endif
			);
	
	public:
		// @note: 占用资源并进入访问
		/*inline*/ BOOL enter();

		// @note: 离开并释放占用资源
		/*inline*/ BOOL leave();
	
	private:
#ifdef WIN32
		CRITICAL_SECTION _cs;
#else
		pthread_mutex_t  _cs;
#endif
	public:
		~xSection(void);
	};

	class xThreadPool;

	//------------------------------------------------------------------------
	// xThread 线程类
	//------------------------------------------------------------------------
	class xThread
	{
		friend class xThreadPool;
	public:
		xThread(void);
		xThread(void * argument
#ifndef WIN32
			,BOOL detach = FALSE
			,u32_t scope = PTHREAD_SCOPE_SYSTEM
			,u32_t inherit = PTHREAD_EXPLICIT_SCHED
			,u32_t policy = SCHED_OTHER
#endif
			,u32_t priority = 0
			);
		/*virtual*/ BOOL stop() { return this->_done = TRUE;    }
	public:
		inline HANDLE operator *() const     { return _handler; }
		inline u32_t getid() const           { return (u32_t)_tid ; }
		inline BOOL active() const           { return !this->_done; }
	public:
		BOOL start(void * argument = NULL
#ifndef WIN32
			,BOOL detach = FALSE
			,u32_t scope = PTHREAD_SCOPE_SYSTEM     // PTHREAD_SCOPE_PROCESS,PTHREAD_SCOPE_SYSTEM
			,u32_t inherit = PTHREAD_EXPLICIT_SCHED // 继承性:PTHREAD_EXPLICIT_SCHED,PTHREAD_INHERIT_SCHED
			,u32_t policy = SCHED_OTHER             // 调度策略:SCHED_FIFO,SCHED_RR,SCHED_OTHER ..
#endif
			,u32_t priority = 0
			);
		BOOL wait(u32_t timeout = INFINITE);
#ifndef WIN32
		void detach();
#endif
		BOOL setpriority(u32_t priority);
		u32_t getpriority();
		void suspend();
		void resume();
	protected:
		// @note:run()运行时调用修改优先级
		BOOL onpriority();
	protected:
		void release();
	protected:
		virtual u32_t __fastcall run(void * argument) = 0;
	protected:
		typedef struct _thread_param_t
		{
			xThread * pthis;
			void * argument;
		}thread_param_t;
		thread_param_t _param;
		pthread_t      _tid;
		u32_t          _priority; // 待修改的优先级
		BOOL           _modify;   // 修改标记
		BOOL           _done;
#ifdef WIN32
		HANDLE         _handler;
//		ESMT::xEvent   _event;
#endif
	private:
		static u32_t __stdcall routine(void * lpParam);
	public:
		virtual ~xThread(void);
	};

	//------------------------------------------------------------------------
	// xThreadPool 线程池
	//------------------------------------------------------------------------
	class xThreadPool
	{
		typedef std::map<u32_t,xThread*> map_id_thread_t;
		typedef map_id_thread_t::iterator itor_id_thread_t;
	public:
		xThreadPool(void);
		void add(xThread * thread);
		void del(u32_t id);
		void clear(void);
		xThread * get(u32_t id);
		size_t size(void);
	public:
		~xThreadPool(void);
	private:
		map_id_thread_t _thread_pool;
	};
} // namespace ESMT

#endif // _XTHREAD_H_INCLUDE_
/*
* @note		:同步事件/信号量/互斥/临界区/线程/线程池实现(win32/linux),不支持unicode
* @author	:Andy.Ro
* @email	:Qwuloo@qq.com
*/

#include "xThread.h"

namespace ESMT {

//------------------------------------------------------------------------
// xSyncObject
//------------------------------------------------------------------------
xSyncObject::xSyncObject(void)
{

}

xSyncObject::~xSyncObject(void)
{

} // class xSyncObject

#ifndef WIN32
static inline int s_pthread_cond_init(pthread_cond_t * cond, int pshared = PTHREAD_PROCESS_PRIVATE)
{
	pthread_condattr_t attr = {0};
	pthread_condattr_init(&attr);
	pthread_condattr_setpshared(&attr, pshared);
	int err = pthread_cond_init(cond, &attr);
	pthread_condattr_destroy(&attr);
	return err;
}
static inline int s_pthread_mutex_init(pthread_mutex_t * mutex, u32_t pshared = PTHREAD_PROCESS_PRIVATE, u32_t type = PTHREAD_MUTEX_TIMED_NP)
{
	pthread_mutexattr_t attr = {0};
	pthread_mutexattr_init(&attr);
	// PTHREAD_PROCESS_PRIVATE:同一进程内不同线程间同步
	// PTHREAD_PROCESS_SHARED :进程间同步
	pthread_mutexattr_setpshared(&attr, pshared);
	// PTHREAD_MUTEX_TIMED_NP     (普通锁):互斥访问
	// PTHREAD_MUTEX_RECURSIVE_NP (嵌套锁)
	// PTHREAD_MUTEX_ERRORCHECK_NP(检错锁)
	// PTHREAD_MUTEX_ADAPTIVE_NP  (适应锁)
	pthread_mutexattr_settype(&attr, type);
	int err = pthread_mutex_init(mutex, &attr);
	pthread_mutexattr_destroy(&attr);
	return err;
}
static inline int s_pthread_mutex_lock(pthread_mutex_t * mutex)
{
	return pthread_mutex_lock(mutex);
}
static inline int s_pthread_mutex_unlock(pthread_mutex_t * mutex)
{
	return pthread_mutex_unlock(mutex);
}
static inline int s_pthread_mutex_trylock(pthread_mutex_t * mutex)
{
	return pthread_mutex_trylock(mutex);
}
static inline int s_pthread_mutex_destroy(pthread_mutex_t * mutex)
{
	return pthread_mutex_destroy(mutex);
}
#endif

//------------------------------------------------------------------------
// xEvent
//------------------------------------------------------------------------
xEvent::xEvent(

			   BOOL initstate /* = FALSE */, BOOL manualreset /* = FALSE */
#ifdef WIN32
			  ,LPCTSTR lpName /* = NULL */, LPSECURITY_ATTRIBUTES lpsa /* = NULL */
#else
			  ,u32_t pshared /* = PTHREAD_PROCESS_PRIVATE */
			  ,u32_t type /* = PTHREAD_MUTEX_TIMED_NP */
#endif
			   )
{
	// 事件内核对象
#ifdef WIN32
	this->_event = CreateEvent(lpsa, manualreset, initstate, lpName);
#else
	bzero(&this->_cond_check, sizeof(cond_check_t));
//	pthread_mutex_init(&this->_mutex, NULL);
//	pthread_cond_init(&this->_cond, NULL);
	s_pthread_mutex_init(&this->_mutex, pshared, type);
	s_pthread_cond_init(&this->_cond, pshared);
	this->_signaled = initstate;
	this->_manual_reset = manualreset;
#endif
}

BOOL xEvent::lock(void)
{
	// 未受信(non-signaled)
	// 人工重置(manual-reset)事件:所有等待在该事件上的线程均变为不可调度状态
	// 自动重置(auto-reset  )事件:调用无效,因为设置事件为受信状态后,系统会立即自动重置为未受信状态,且仅
	//                          允许一个等待在该事件上的线程变为可调度状态,挂起其他等待在该事件上的线程
#ifdef WIN32
	return ResetEvent(this->_event);
#else
	pthread_mutex_lock(&this->_mutex);
	if ( this->_manual_reset )
	{
		this->_signaled = FALSE;
	}
	return 0 == pthread_mutex_unlock(&this->_mutex);
#endif
}

BOOL xEvent::wait(ulong_t timeout /* = INFINITE */)
{
#ifdef WIN32
	return WAIT_OBJECT_0 == WaitForSingleObject(this->_event, timeout);
#else
	pthread_mutex_lock(&this->_mutex);
#if 0
	while( this->_cond_check._handler && !(*this->_cond_check._handler)(this->cond_check._args) )
#else
	while( !this->_signaled )
#endif
	{
		if ( INFINITE == timeout )
		{
			if ( pthread_cond_wait(&this->_cond, &this->_mutex) )
			{
				 pthread_mutex_unlock(&this->_mutex);
				 return -1;
			}
		}
		else {
			// timeout:毫秒 tv_usec:微秒 tv_nsec:纳秒
			struct timeval tv = {0};
			struct timespec abstm = {0};
			gettimeofday(&tv, NULL);
			abstm.tv_sec = tv.tv_sec + timeout / 1000;
			abstm.tv_nsec = tv.tv_usec * 1000 + (timeout % 1000) * 1000000;
			int err;
			if ( err = pthread_cond_timedwait(&this->_cond, &this->_mutex, &abstm) )
			{
				if (ETIMEDOUT == err ) {
					break;
				}
				pthread_mutex_unlock(&this->_mutex);
				return -1;
			}
		}
	}
	// 自动重置(auto-reset  )事件受信后,立即重置为未受信状态
	if ( !this->_manual_reset )
	{
		this->_signaled = FALSE;
	}
	return 0 == pthread_mutex_unlock(&this->_mutex);
#endif
}

BOOL xEvent::unlock(void)
{
	// 受信(signaled)
	// 人工重置(manual-reset)事件:所有等待在该事件上的线程均变为可调度状态
	// 自动重置(auto-reset  )事件:仅允许一个等待在该事件上的线程变为可调度状态,然后系统立即自动重置为未受信状态,
	//                          挂起其他等待在该事件上的线程
#ifdef WIN32
	return SetEvent(this->_event);
#else
	pthread_mutex_lock(&this->_mutex);
	this->_signaled = TRUE;
	int err = this->_manual_reset?pthread_cond_broadcast(&this->_cond):pthread_cond_signal(&this->_cond);
	pthread_mutex_unlock(&this->_mutex);
	return 0 == err;
#endif
}
#pragma endregion

xEvent::~xEvent(void)
{
#ifdef WIN32
	SAFE_DEL_HDL(this->_event);
#else
	this->_signaled = TRUE;
	pthread_cond_destroy(&this->_cond);
	pthread_mutex_destroy(&this->_mutex);
#endif
	
} // class xEvent

//------------------------------------------------------------------------
// xSemaphore
//------------------------------------------------------------------------
xSemaphore::xSemaphore(ulong_t initvalue /* = 1 */
#ifdef WIN32
					  ,ulong_t maxvalue /* = 1 */
#endif
	                  ,char const * name /* = NULL */)
{
	// 信号量内核对象
#ifdef WIN32
	if ( !(this->_sem = CreateSemaphore(NULL, initvalue, maxvalue, (LPCTSTR)name)) )
	{
		if ( ERROR_ALREADY_EXISTS == GetLastError() )
		{
			if( !(this->_sem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, (LPCTSTR)name)) )
			{
//				fprintf(stderr, "OpenSemaphore error: %s\n",  strerror(GetLastError()));
				perror("OpenSemaphore error");
			}
			return;
		}
//		fprintf(stderr, "CreateSemaphore error: %s\n", strerror(GetLastError()));
		perror("CreateSemaphore error");
	}
#else
	if( !name )
	{
		// 初始化一个进程内线程间共享的匿名信号量
		// 进程间共享则第二个参数pshared必须大于0,且须定位共享内存区( shm_open,mmap,shmget,shmat),要注意的是匿名信号量的值是保存在内存中,所以只能用于亲缘进程间共享
		if( sem_init(&this->_sem, 0, min(initvalue, SEM_VALUE_MAX)) < 0 )
		{
//			fprintf(stderr, "sem_init error: %s\n", strerror(errno));
			perror("sem_init error");
			bzero(&this->_sem, sizeof(sem_t));
		}
	}
	else {
		// 打开一个有名信号量,没有则创建,既可用于进程内线程间,亲缘进程间,也可用于不相干进程间共享
		// 注意:第一次创建,第二次打开,initvalue 值设为 0,用于共享同步访问
		if( SEM_FAILED == (this->_p_sem = sem_open(name, O_CREAT, 0644, min(initvalue, SEM_VALUE_MAX))) ) {
//			fprintf(stderr, "sem_open error: %s\n", strerror(errno));
			perror("sem_open error");
			sem_unlink(name);
			this->_p_sem = NULL;
			return;
		}
		this->_S_NAME = name;
	}
#endif
}

BOOL xSemaphore::enter(void)
{
#ifdef WIN32
	return WAIT_OBJECT_0 == WaitForSingleObject(this->_sem, INFINITE);
#else
	return 0 == sem_wait(this->_p_sem?this->_p_sem:&this->_sem); // P操作,即申请资源
#endif
}

BOOL xSemaphore::leave(void)
{
#ifdef WIN32
	return ReleaseSemaphore(this->_sem, 1, NULL);
#else
	return 0 == sem_post(this->_p_sem?this->_p_sem:&this->_sem); // V操作,即释放资源
#endif
}

xSemaphore::~xSemaphore(void)
{
#ifdef WIN32
	SAFE_DEL_HDL(this->_sem);
#else
	this->_p_sem?sem_close(this->_p_sem):sem_destroy(this->_sem);
	this->_p_sem?sem_unlink(this->_S_NAME.c_str());
	this->_p_sem = NULL;
	bzero(&this->_sem, sizeof(sem_t));
#endif
	
} // class xSemaphore

//------------------------------------------------------------------------
// xMutex
//------------------------------------------------------------------------
xMutex::xMutex(
#ifdef WIN32
	LPCTSTR lpName /* = NULL */, BOOL bInitOwner /* = FALSE */, LPSECURITY_ATTRIBUTES lpsa /* = NULL */
#else
	,u32_t pshared /* = PTHREAD_PROCESS_PRIVATE */
	,u32_t type /* = PTHREAD_MUTEX_TIMED_NP */
#endif
	)
{
	// 互斥内核对象只有一个,仅拥有互斥对象的线程才具有访问资源权限,互斥访问共享资源时只能一个线程占用并访问,
	// 访问完后占用资源的线程要释放当前占用资源(交出拥有的互斥内核对象),以让其他线程再竞争占用共享资源进行互斥访问
#ifdef WIN32
	this->_mutex = CreateMutex(lpsa, bInitOwner, lpName);
#else
	s_pthread_mutex_init(&this->_mutex, pshared, type);
#endif
}

/*inline*/ BOOL xMutex::enter(void)
{
#ifdef WIN32
	return WAIT_OBJECT_0 == WaitForSingleObject(this->_mutex, INFINITE);
#else
	return 0 == s_pthread_mutex_lock(&this->_mutex);
#endif
}

/*inline*/ BOOL xMutex::leave(void)
{
	// 释放互斥对象
#ifdef WIN32
	return ReleaseMutex(this->_mutex);
#else
	return 0 == s_pthread_mutex_unlock(&this->_mutex);
#endif
}

xMutex::~xMutex(void)
{
#ifdef WIN32
	SAFE_DEL_HDL(this->_mutex);
#else
	s_pthread_mutex_destroy(&this->_mutex);
#endif
} // class xMutex

//------------------------------------------------------------------------
// xSection
//------------------------------------------------------------------------
xSection::xSection(
#ifdef WIN32
#else
	 u32_t pshared /* = PTHREAD_PROCESS_PRIVATE */
	,u32_t type /* = PTHREAD_MUTEX_TIMED_NP */
#endif
	)
{
	// 使用临界区对象能实现多线程对共享数据的同步访问,但是非内核对象,所以不能用于进程间线程同步
#ifdef WIN32
	InitializeCriticalSection(&this->_cs);
#else
	s_pthread_mutex_init(&this->_cs, pshared, type);
#endif
}

/*inline*/ BOOL xSection::enter(void)
{
#ifdef WIN32
	EnterCriticalSection(&this->_cs);
#else
	return 0 == s_pthread_mutex_lock(&this->_cs);
#endif
	return TRUE;
}

/*inline*/ BOOL xSection::leave(void)
{
#ifdef WIN32
	LeaveCriticalSection(&this->_cs);
#else
	return 0 == s_pthread_mutex_unlock(&this->_cs);
#endif
	return TRUE;
}

xSection::~xSection(void)
{
#ifdef WIN32
	DeleteCriticalSection(&this->_cs);
#else
	s_pthread_mutex_destroy(&this->_cs);
#endif
} // class xSection

//------------------------------------------------------------------------
// xThread
//------------------------------------------------------------------------
xThread::xThread()
	:_tid(0)
	,_priority(0)
	,_done(FALSE)
	,_modify(FALSE)
#ifdef WIN32
	,_handler(NULL)
#endif
{
	bzero(&this->_param, sizeof(thread_param_t));
}

xThread::xThread(void * argument
#ifndef WIN32
	,BOOL detach /* = FALSE */
	,u32_t scope /* = PTHREAD_SCOPE_SYSTEM */
	,u32_t inherit /* = PTHREAD_EXPLICIT_SCHED */
	,u32_t policy /* = SCHED_OTHER */
#endif
	,u32_t priority /* = 0 */
	)
	:_tid(0)
	,_priority(0)
	,_done(FALSE)
	,_modify(FALSE)
#ifdef WIN32
	,_handler(NULL)
#endif
{
	bzero(&this->_param, sizeof(thread_param_t));
	this->start(argument
#ifndef WIN32
		,detach
		,scope
		,inherit
		,policy
#endif
		,priority
		);
}

BOOL xThread::start(void * argument /* = NULL */
#ifndef WIN32
	,BOOL detach /* = FALSE */
	,u32_t scope /* = PTHREAD_SCOPE_SYSTEM */
	,u32_t inherit /* = PTHREAD_EXPLICIT_SCHED */
	,u32_t policy /* = SCHED_OTHER */
#endif
	,u32_t priority /* = 0 */
	)
{
	if( !this->_tid )
	{
		bzero(&this->_param, sizeof(thread_param_t));
		this->_param.pthis    = this;
		this->_param.argument = argument;
#ifdef WIN32
		// ...
		_handler = (HANDLE)_beginthreadex(NULL,			            // security
										  0,                        // stack size
										  xThread::routine,         // start address
										  (void *)&this->_param,    // argument list
										  0,                        // init flag:0 | CREATE_SUSPENDED
										  (unsigned *)&this->_tid); // thread id
		if( !this->_tid ) {
//			fprintf(stderr, "_beginthreadex error: %s\n", strerror(GetLastError()));
			perror("_beginthreadex error");
			return FALSE;
		}
		this->setpriority(priority);
//		SAFE_DEL_HDL(_handler);
#else
		pthread_attr_t atrr = {0};
		pthread_attr_init(&attr);
		pthread_attr_setscope(&attr, scope);
		pthread_attr_setinheritsched(&attr, inherit);
		PTHREAD_EXPLICIT_SCHED == inherit?pthread_attr_setschedpolicy(&attr, policy):0;
		detach?pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)
			  :pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
		if ( SCHED_RR == policy || SCHED_FIFO == policy ) {
			sched_param param = {0};
			priority = MIN(priority,sched_get_priority_max(policy));
			priority = MAX(priority,sched_get_priority_min(policy));
			pthread_attr_getschedparam(&attr, ¶m);
			param.sched_priority = priority;
			pthread_attr_setschedparam(&attr, ¶m);
		}
		// ...
		int err;
		if ( err = pthread_create(&this->_tid, attr, xThread::routine, (void *)argument) ) {
//			fprintf(stderr, "pthread_create error: %s\n", strerror(err));
			perror("pthread_create error");
			pthread_attr_destroy(&attr);
			return FALSE;
		}
		pthread_attr_destroy(&attr);
#endif
		this->_done = FALSE;
	}
	return 0 != this->_tid;
}

u32_t __stdcall xThread::routine(void * lpParam)
{
	thread_param_t * pParam = (thread_param_t *)lpParam;

	u32_t result = pParam->pthis->run(pParam->argument);
	
//	__signaled(pParam->pthis->_event);

	pParam->pthis->release();

#ifdef WIN32
	_endthreadex(0);
#else
	pthread_exit(0);
#endif
	
	return result;
}

BOOL xThread::wait(u32_t timeout /* = INFINITE */)
{
#ifdef WIN32
	assert( this->_handler );
#if 1
	return WAIT_FAILED != WaitForSingleObject(this->_handler, timeout);
#else
	// 等待线程运行结束退出,线程创建后句柄已被关闭,换用事件方式
	return __wait_signal(this->_event, timeout);
#endif
#else
	assert( this->_tid );
	return 0 == pthread_join(this->_tid, NULL);
#endif
}

#ifndef WIN32
void xThread::detach()
{
	pthread_detach(this->_tid);
}
#endif

BOOL xThread::setpriority(u32_t priority)
{
#ifdef WIN32
#else
	u32_t policy;
	sched_param param = {0};
	pthread_getschedparam(this->_tid, &policy, ¶m);
	if ( SCHED_RR != policy || SCHED_FIFO != policy )
	{
		return FALSE;
	}
	priority = MIN(priority,sched_get_priority_max(policy));
	priority = MAX(priority,sched_get_priority_min(policy));
#endif
	this->_priority = priority;
	this->_modify = TRUE;
	return TRUE;
}

// @note:线程运行时调用修改优先级
BOOL xThread::onpriority()
{
	if ( this->_modify )
	{
		this->_modify = FALSE;
#ifdef WIN32
		assert( this->_tid == GetThreadId(_handler) );
		return SetThreadPriority(_handler, this->_priority);
#else
		assert( this->_tid == pthread_self() );
		u32_t policy;
		sched_param param = {0};
		pthread_getschedparam(this->_tid, &policy, ¶m);
		assert( SCHED_RR == policy || SCHED_FIFO == policy );
		param.sched_priority = this->_priority;
		pthread_setschedparam(this->_tid,  policy, ¶m);
#endif
	}
	return TRUE;
}

u32_t xThread::getpriority()
{
#ifdef WIN32
	assert( this->_tid && this->_handler );
	return GetThreadPriority(this->_handler);
#else
	assert( this->_tid );
	u32_t policy;
	sched_param param;
	pthread_getschedparam(this->_tid, &policy, ¶m);
	return param.sched_priority;
#endif
}

void xThread::suspend()
{
#ifdef WIN32
	SuspendThread(_handler);
#endif
}

void xThread::resume()
{
#ifdef WIN32
	ResumeThread(_handler);
#endif
}

void xThread::release()
{
	SAFE_DEL_HDL(_handler);
	this->_tid = 0;
	bzero(&this->_param, sizeof(thread_param_t));
}

xThread::~xThread()
{
	release();
} // class xThread

//------------------------------------------------------------------------
// xThreadPool
//------------------------------------------------------------------------
xThreadPool::xThreadPool(void)
{
	this->_thread_pool.clear();
}

void xThreadPool::add(xThread * thread)
{
	this->_thread_pool[thread->getid()] = thread;
}

void xThreadPool::del(u32_t id)
{
	itor_id_thread_t itor = this->_thread_pool.find(id);
	if ( itor != this->_thread_pool.end() )
	{
		// 关闭指定线程
		itor->second->stop();
		
		BOOL delflag = FALSE;
		
		while ( !delflag )
		{
			// 挂起调用线程等待指定线程结束
			if (  __wait_signal(*itor->second,1000) )
			{
				delflag = TRUE;
				SAFE_DEL(itor->second);
				this->_thread_pool.erase(itor);
			}
		}
	}
}

void xThreadPool::clear(void)
{
	// 线程池中还有残留线程
	while ( this->_thread_pool.size() )
	{
		itor_id_thread_t itor = this->_thread_pool.begin();
		for ( ; itor != this->_thread_pool.end(); )
		{
			// 关闭指定线程
			itor->second->stop();

			// 挂起调用线程等待指定线程结束
			if ( __wait_signal(*itor->second,1000) )
			{ 
				SAFE_DEL(itor->second);
				this-> _thread_pool.erase(itor);
				itor = _thread_pool.begin();
				continue;
			}
			++itor;
		}
	}
}

xThread * xThreadPool::get(u32_t id)
{
	return this->_thread_pool[id];
}

size_t xThreadPool::size(void)
{
	return this->_thread_pool.size();
}

xThreadPool::~xThreadPool(void)
{
	this->clear();
} // class xThreadPool

} // namespace ESMT


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值