📄 threadrunner.h
字号:
#pragma once
#include <atldef.h>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <process.h>
class CThreadRunner
{
private:
class _CThreadRunnerImpl
{
private:
_CThreadRunnerImpl();
~_CThreadRunnerImpl();
public:
HRESULT Start(const void* _reserved, const boost::function0<void>& threadfunc);
HRESULT Stop();
bool IsRunning();
bool HasStopSignal();
HRESULT Wait();
HRESULT Sleep(DWORD ms);
private:
static unsigned __stdcall _CrtThreadProc(void* pThis);
void _ThreadProc();
private:
void _ClearThreadRes();
private:
boost::function0<void> m_threadfunc;
HANDLE m_ThreadHandle;
DWORD m_ThreadID;
HANDLE m_StoppingEvent;
public:
static _CThreadRunnerImpl* RawCreateInstance();
void RawAddRef();
void RawRelease();
private:
LONG m_ref;
};
public:
CThreadRunner()
: m_pImpl(_CThreadRunnerImpl::RawCreateInstance())
{ATLASSERT(m_pImpl != NULL);}
~CThreadRunner()
{ATLASSERT(!m_pImpl->IsRunning() || m_pImpl->HasStopSignal()); m_pImpl->Stop(); m_pImpl->RawRelease();} //放宽了检查:+ HasStopSignal
public:
HRESULT Start(const void* _reserved, const boost::function0<void>& threadfunc)
{return m_pImpl->Start(_reserved, threadfunc);}
HRESULT Stop()
{return m_pImpl->Stop();}
bool IsRunning()
{return m_pImpl->IsRunning();}
bool HasStopSignal()
{return m_pImpl->HasStopSignal();}
HRESULT Wait()
{return m_pImpl->Wait();}
HRESULT Sleep(DWORD ms)
{return m_pImpl->Sleep(ms);}
private:
_CThreadRunnerImpl* m_pImpl;
};
//////////////////////////////////////////////////////////////////////////
inline
CThreadRunner::_CThreadRunnerImpl::_CThreadRunnerImpl() :
m_ThreadHandle(0), m_ThreadID(0),
m_ref(1)
{
m_StoppingEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
}
inline
CThreadRunner::_CThreadRunnerImpl::~_CThreadRunnerImpl()
{
_ClearThreadRes();
::CloseHandle(m_StoppingEvent);
}
inline
HRESULT CThreadRunner::_CThreadRunnerImpl::Start(const void* _reserved, const boost::function0<void>& threadfunc)
{
if (IsRunning())
return E_UNEXPECTED;
_ClearThreadRes();
m_ThreadHandle = (HANDLE)_beginthreadex(NULL, 0, _CrtThreadProc, this, CREATE_SUSPENDED, (unsigned*)&m_ThreadID);
if (m_ThreadHandle == 0)
return E_FAIL;
m_threadfunc = threadfunc;
::ResetEvent(m_StoppingEvent);
RawAddRef(); //for _ThreadProc
::ResumeThread(m_ThreadHandle);
return S_OK;
}
inline
HRESULT CThreadRunner::_CThreadRunnerImpl::Stop()
{
::SetEvent(m_StoppingEvent);
return S_OK;
}
inline
bool CThreadRunner::_CThreadRunnerImpl::IsRunning()
{
if (m_ThreadHandle == NULL)
return false;
return ::WaitForSingleObject(m_ThreadHandle, 0) != WAIT_OBJECT_0;
}
inline
bool CThreadRunner::_CThreadRunnerImpl::HasStopSignal()
{
// ATLASSERT(m_ThreadID == ::GetCurrentThreadId());
return ::WaitForSingleObject(m_StoppingEvent, 0) == WAIT_OBJECT_0;
}
inline
HRESULT CThreadRunner::_CThreadRunnerImpl::Wait()
{
if (m_ThreadHandle == 0)
return S_FALSE;
if (m_ThreadID == 0)
return S_FALSE;
if (m_ThreadID == ::GetCurrentThreadId())
return E_ACCESSDENIED;
::WaitForSingleObject(m_ThreadHandle, -1);
_ClearThreadRes();
return S_OK; //thread if finish
}
inline
HRESULT CThreadRunner::_CThreadRunnerImpl::Sleep(DWORD ms)
{
if (m_ThreadID != ::GetCurrentThreadId())
{
ATLASSERT(FALSE);
//不在本线程中,简单sleep
::Sleep(ms);
return S_FALSE;
}
if (::WaitForSingleObject(m_StoppingEvent, ms) == WAIT_TIMEOUT)
return S_OK;
return E_FAIL;
}
//static
inline
unsigned __stdcall CThreadRunner::_CThreadRunnerImpl::_CrtThreadProc(void* pThis)
{
ATLASSERT(pThis != NULL);
((_CThreadRunnerImpl*)pThis)->_ThreadProc();
return 0;
}
inline
void CThreadRunner::_CThreadRunnerImpl::_ThreadProc()
{
{{
#ifndef _DEBUG
try
#endif
{ m_threadfunc(); }
#ifndef _DEBUG
catch (...)
{ ATLASSERT(FALSE); }
#endif
}}
RawRelease(); //end
}
inline
void CThreadRunner::_CThreadRunnerImpl::_ClearThreadRes()
{
if (m_ThreadHandle != NULL)
::CloseHandle(m_ThreadHandle);
m_ThreadHandle = 0;
m_ThreadID = 0;
}
//static
inline
CThreadRunner::_CThreadRunnerImpl* CThreadRunner::_CThreadRunnerImpl::RawCreateInstance()
{
return new _CThreadRunnerImpl();
}
inline
void CThreadRunner::_CThreadRunnerImpl::RawAddRef()
{
ATLASSERT(m_ref > 0);
::InterlockedIncrement(&m_ref);
}
inline
void CThreadRunner::_CThreadRunnerImpl::RawRelease()
{
ATLASSERT(m_ref > 0);
if (::InterlockedDecrement(&m_ref) == 0)
delete this;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -