multi-thread

win32 方式

c++ 方式

CPP RunTime Library

_beginthreadex, _endthreadex
_endthreadex need calling the Win32 CloseHandle API

注意:在使用了MFC的程序中不能够使用该函数创建线程,而应该使用MFC提供的线程函数
MFC relies on some thread - local variables and state.AfxBeginThread
initializes those, then calls _beginthreadex for you.Just part of the
preconditions for using the library.If you don’t use AfxBeginThread some
of your calls to MFC functions could encounter uninitialized pointers.

//_beginthread use
#include <process.h>

//friend function can access private member
friend unsigned int __stdcall threadReadProc(void* pArguments);

//monitor thread use
HANDLE hThread;

void startListener()
{
// Create the second thread.
m_hThreadPay = (HANDLE)_beginthreadex(NULL, 0, &threadReadProc, this, 0, NULL);
if (NULL == m_hThread)
{
return RET_FAILED;
}
// Wait until second thread terminates. If you comment out the line
// below, Counter will not be correct because the thread has not
// terminated, and Counter most likely has not been incremented to
// 1000000 yet.
WaitForSingleObject(m_hThreadPay, INFINITE);
printf("Counter should be 1000000; it is-> %d\n", Counter);
// Destroy the thread object.
CloseHandle(m_hThreadPay);
_endthreadex(0);

}

unsigned int __stdcall threadReadProc(void* pArguments)
{
CMainDlg* pwnd = (CMainDlg*)pArguments;
::WaitForSingleObject(hEvent, INFINITE);
...
CloseHandle(hThread);
g_hThreadProc = NULL;
_endthreadex(0);//ensure proper recovery of resources allocated for the thread.
return 0;
}

暂停线程

对于暂停线程可以使用信号量来控制

//seconde param TRUE manual reset, FALSE auto-reset, third param initial state
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

在需要暂停的地方用
::WaitForSingleObject(hEvent, -1);

// 最多等待 10 s
WaitForMultipleObjects(m_curInfo.vEvtThread.size(), &m_curInfo.vEvtThread[0], TRUE, 10000);

::SetEvent(hEvent);//go on
::ResetEvent(hEvent);//pause

MFC 方式

// 启动时,设置优先级
AfxBeginThread(threadWorkerFrontend, this, THREAD_PRIORITY_TIME_CRITICAL);

CWinThread* m_pThread = AfxBeginThread(threadReadProc, this);
UINT threadReadProc(LPVOID lpParam)
{
while (iAbort == 0)
{

}
return 0;
}

iAbort = 1;
::WaitForSingleObject(m_pThread->m_hThread, INFINITE);

m_pThread->SuspendThread();
m_pThread->ResumeThread();

AfxEndThread(0);
TerminateThread(m_pThread, 0);

参考代码,这里的 CWinThread 会在线程结束后自动释放。

工作线程

CWinThread* m_pThread = AfxBeginThread(threadReadProc, this);
UINT threadReadProc(LPVOID lpParam)
{
while (iAbort == 0)
{

}
return 0;
}

iAbort = 1;
::WaitForSingleObject(m_pThread->m_hThread, INFINITE);

m_pThread->SuspendThread();
m_pThread->ResumeThread();

AfxEndThread(0);
TerminateThread(m_pThread, 0);

更新UI界面

使用自定义消息

// 更新统计界面数据
#define WM_UIMESSAGE (WM_USER + 201)

BEGIN_MESSAGE_MAP(CDlgQueryPeople, CDialogEx)
...
ON_MESSAGE(WM_UIMESSAGE, &CnngDemoServerDlg::OnUIMessage)
END_MESSAGE_MAP()

LRESULT CDlgQueryPeople::OnUIMessage(WPARAM wParam, LPARAM lParam)
{
if (wParam != 0) {
int cnt = m_list_statistic.GetItemCount();
m_list_statistic.InsertItem(cnt, *((CString*)wParam));
}

return 0;
}

afx_msg LRESULT OnUIMessage(WPARAM wParam, LPARAM lParam);