有一个工作线程来专门处理是比较经典的应用。下面是样例代码:
1、有一容器,主线程会把子任务放入此容器中,然后由工作线程来取容器内容,完成任务。
CReport::CReport()
{
m_nFrequence = RF_NORMAL;
m_bStop = FALSE;
::InitializeCriticalSection(&m_csContainer);
}
CReport::~CReport()
{
::DeleteCriticalSection(&m_csContainer);
}
BOOL CReport::Start()
{
DWORD dwThread;
m_hThread = ::CreateThread(NULL, 0, _WorkThread, this, CREATE_SUSPENDED, &dwThread);
ERROR_CHECK_BOOL(m_hThread);
return m_CURL.Init();
Exit0:
return FALSE;
}
void CReport::Stop()
{
::InterlockedExchange(&m_bStop, TRUE);
::WaitForSingleObject(m_hThread, INFINITE);
}
void CReport::AddReport(LPCTSTR szReport)
{
::EnterCriticalSection(&m_csContainer);
m_Container.push_back(szReport);
::ResumeThread(m_hThread);
::LeaveCriticalSection(&m_csContainer);
}
//
//
DWORD WINAPI CReport::_WorkThread(LPVOID lpThreadParameter)
{
CReport *This = (CReport*)lpThreadParameter;
ATL::CString strReport;
BOOL bHasWork = TRUE;
while (!This->m_bStop)
{
// Normal
::EnterCriticalSection(&This->m_csContainer);
strReport = This->m_Container.front();
::LeaveCriticalSection(&This->m_csContainer);
// 每次只一个发包
BOOL bRet = This->m_CURL.ExchangeDateToServer(strReport); // Work
if (bRet) // 成功后把包弹出任务栈
{
::EnterCriticalSection(&This->m_csContainer);
This->m_Container.pop_front();
bHasWork = This->m_Container.size() > 0;
::LeaveCriticalSection(&This->m_csContainer);
}
// 退出标志
if (This->m_bStop)
break;
// 判断是否还有工作要做
if (!bHasWork)
::SuspendThread(This->m_hThread);
bHasWork = TRUE;
::Sleep(5000); // 避免连续上报引起CPU占用
}
return 0;
}
此例子主要是演示把线程挂起来,直到有人AddReport时才唤醒线程。此例子比普通不断检查hStopEvent,通过超时来减少CPU占用率的做法要好很多。
2、Other...
1、有一容器,主线程会把子任务放入此容器中,然后由工作线程来取容器内容,完成任务。
CReport::CReport()
{
m_nFrequence = RF_NORMAL;
m_bStop = FALSE;
::InitializeCriticalSection(&m_csContainer);
}
CReport::~CReport()
{
::DeleteCriticalSection(&m_csContainer);
}
BOOL CReport::Start()
{
DWORD dwThread;
m_hThread = ::CreateThread(NULL, 0, _WorkThread, this, CREATE_SUSPENDED, &dwThread);
ERROR_CHECK_BOOL(m_hThread);
return m_CURL.Init();
Exit0:
return FALSE;
}
void CReport::Stop()
{
::InterlockedExchange(&m_bStop, TRUE);
::WaitForSingleObject(m_hThread, INFINITE);
}
void CReport::AddReport(LPCTSTR szReport)
{
::EnterCriticalSection(&m_csContainer);
m_Container.push_back(szReport);
::ResumeThread(m_hThread);
::LeaveCriticalSection(&m_csContainer);
}
//
//
DWORD WINAPI CReport::_WorkThread(LPVOID lpThreadParameter)
{
CReport *This = (CReport*)lpThreadParameter;
ATL::CString strReport;
BOOL bHasWork = TRUE;
while (!This->m_bStop)
{
// Normal
::EnterCriticalSection(&This->m_csContainer);
strReport = This->m_Container.front();
::LeaveCriticalSection(&This->m_csContainer);
// 每次只一个发包
BOOL bRet = This->m_CURL.ExchangeDateToServer(strReport); // Work
if (bRet) // 成功后把包弹出任务栈
{
::EnterCriticalSection(&This->m_csContainer);
This->m_Container.pop_front();
bHasWork = This->m_Container.size() > 0;
::LeaveCriticalSection(&This->m_csContainer);
}
// 退出标志
if (This->m_bStop)
break;
// 判断是否还有工作要做
if (!bHasWork)
::SuspendThread(This->m_hThread);
bHasWork = TRUE;
::Sleep(5000); // 避免连续上报引起CPU占用
}
return 0;
}
此例子主要是演示把线程挂起来,直到有人AddReport时才唤醒线程。此例子比普通不断检查hStopEvent,通过超时来减少CPU占用率的做法要好很多。
2、Other...