实现跨平台的C++线程库

    完整工程代码放在我的github上:https://github.com/yjwwyygy/CrossPlatformLibrary

    实现一个跨平台的线程基类,需要使用线程时,继承该基类,实现表示线程运行体的虚函数即可。

    直接贴代码,注意注释即可。

#ifndef THREAD_BASE_H
#define THREAD_BASE_H

#include "mutex.h"
#include "base_def.h"

#ifdef WIN32
#include 
#else
#include  
#include 
#endif

#ifndef INFINITE
#define INFINITE 0xFFFFFFFF
#endif

void BASE_EXPORT SleepMill(int ms);

class BASE_EXPORT ThreadBase
{
public:
	ThreadBase();
	virtual ~ThreadBase();

	// 启动线程
	void Start();

	// 等待线程退出
	bool Wait(unsigned long milli = INFINITE);

	// 判断线程是否正在运行
	bool IsRunning();

	// 停止线程,调用后可以调用wait等待线程真正完全退出
	void Terminate();

	// 获取线程ID
	int GetThreadId() { return m_nThreadId; }

protected:
	// 子类必须以该函数作为循环的条件,以保证调用terminate时能安全退出线程
	bool IsBreak();

	// 线程运行体
	virtual void Run() = 0;

private:
#ifdef WIN32
	unsigned int m_nThreadId;
	HANDLE m_hThread;
	static int ThreadProc(void *arg);
#else
	pthread_t m_nThreadId;
	static void *ThreadProc(void *arg);
#endif

	bool m_bBreak;
	Mutex m_mutex;
};

#endif
#include "thread_base.h"

#ifdef WIN32
#include 
typedef unsigned (__stdcall * ThreadStartProc) (void *);

ThreadBase::ThreadBase()
: m_hThread(NULL)
, m_nThreadId(0)
, m_bBreak(false)
{
}

ThreadBase::~ThreadBase()
{
	if (IsRunning())
	{
		Terminate();
		Wait();

		BOOL ret = CloseHandle(m_hThread);
		WIN_ASSERT(TRUE == ret);
		m_hThread = NULL;
	}
}

void ThreadBase::Start()
{
	if (IsRunning())
	{
		return;
	}

	if (NULL != m_hThread)
	{
		BOOL ret = CloseHandle(m_hThread);
		WIN_ASSERT(TRUE == ret);
		m_hThread = NULL;
	}

	m_bBreak = false;
	m_hThread = (HANDLE)_beginthreadex(NULL, 0, (ThreadStartProc)ThreadProc, this, 0, &m_nThreadId);
	ERRNO_ASSERT(NULL != m_hThread);
	BASE_ASSERT(0 != m_nThreadId);
}

bool ThreadBase::Wait(unsigned long milli /*= INFINITE*/)
{
	if (!IsRunning())
	{
		return true;
	}

	DWORD ret = WaitForSingleObject(m_hThread, milli);
	if (WAIT_OBJECT_0 == ret)
	{
		return true;
	}
	else if (WAIT_TIMEOUT == ret)
	{
		return false;
	}

	WIN_ASSERT(0);

	return false;
}

bool ThreadBase::IsRunning()
{
	HT_CS(m_mutex);
	return 0 != m_nThreadId;
}

void ThreadBase::Terminate()
{
	HT_CS(m_mutex);
	m_bBreak = true;
}

bool ThreadBase::IsBreak()
{
	HT_CS(m_mutex);
	return m_bBreak;
}

int ThreadBase::ThreadProc(void *arg)
{
	ThreadBase *pThis = (ThreadBase*)arg;
	pThis->Run();
	HT_CS(pThis->m_mutex);
	pThis->m_nThreadId = 0;
	return 0;
}

#else

ThreadBase::ThreadBase()
: m_nThreadId(0)
, m_bBreak(false)
{
}


ThreadBase::~ThreadBase()
{
	if (IsRunning())
	{
		Terminate();
		Wait();
	}
}

void ThreadBase::Start()
{
	if (IsRunning())
	{
		return;
	}

	m_bBreak = false;
	int ret = pthread_create(&m_nThreadId, NULL, ThreadProc, this);
	POSIX_ASSERT(ret);
}

bool ThreadBase::Wait(unsigned long milli /*= INFINITE*/)
{
	if (!IsRunning())
	{
		return true;
	}

	int ret = pthread_join(m_nThreadId, NULL);
	POSIX_ASSERT(ret);

	return true;
}

bool ThreadBase::IsRunning()
{
	HT_CS(m_mutex);
	return 0 != m_nThreadId;
}

void ThreadBase::Terminate()
{
	HT_CS(m_mutex);
	m_bBreak = true;
}

bool ThreadBase::IsBreak()
{
	HT_CS(m_mutex);
	return m_bBreak;
}

int ThreadBase::ThreadProc(void *arg)
{
	ThreadBase *pThis = (ThreadBase*)arg;
	pThis->Run();
	HT_CS(pThis->m_mutex);
	pThis->m_nThreadId = 0;
	return 0;
}

#endif

void SleepMill(int ms)
{
#ifdef WIN32
	Sleep(ms);
#else
	usleep(ms * 1000);
#endif
}

你可能感兴趣的:(跨平台C++开发)