导航

线程通信:Alertable IO

Posted on 2010-03-13 22:47  hcfalan  阅读(367)  评论(0编辑  收藏  举报
发现这个在线程等待多个事件,并且是要求所有等待事件触发的情况,唯一可用到退出线程体的一种方式。代码:

//回调函数,什么也不做
static void WINAPI ApcFun(ULONG_PTR)
{
// do nothing here
}

//线程体,等待两个事件Event1, Event2
DWORD CThreadDemoDlg::ThreadBody()
{
m_szOutput.Append(L"Thread started.\r\n");
PostMessage(WM_USERMSG);

m_szOutput.Append(L"Waiting for events...\r\n");
PostMessage(WM_USERMSG);

HANDLE es[2] = { m_hEvent1, m_hEvent2 };
DWORD dwResult = 0;

LBL_WAIT:
  // 注意这里使用的是WaitXXXEx版,最后一个参数标识为Alertable
dwResult = WaitForMultipleObjectsEx(2, es, TRUE, INFINITE, TRUE);

if (dwResult >= WAIT_OBJECT_0 && dwResult < (WAIT_OBJECT_0+2))
{ //所有事件被触发
m_szOutput.Append(L"Events signed.\r\n");
PostMessage(WM_USERMSG);
goto LBL_WAIT;
}

if (dwResult == WAIT_IO_COMPLETION)
{ //Alertable IO here(after you call QueueUserAPC)
m_szOutput.Append(L"APC queued.\r\n");
PostMessage(WM_USERMSG);
}

m_szOutput.Append(L"Exiting thread.\r\n");
PostMessage(WM_USERMSG);

return 0;
}

// Start Thread
void CThreadDemoDlg::OnBnClickedStartThread()
{
if (m_hEvent1 == NULL)
m_hEvent1 = CreateEvent(NULL, NULL, FALSE, NULL);
if (m_hEvent2 == NULL)
m_hEvent2 = CreateEvent(NULL, NULL, FALSE, NULL);
if (m_hThread)
{
CloseHandle(m_hThread);
m_hThread = NULL;
}

m_hThread = CreateThread(NULL, NULL, ThreadRun, this, NULL, NULL);
}

// Set Events
void CThreadDemoDlg::OnBnClickedSetEvent()
{
SetEvent(m_hEvent1);
SetEvent(m_hEvent2);
}

// Exit Thread
void CThreadDemoDlg::OnBnClickedExitThread()
{
QueueUserAPC(ApcFun, m_hThread, NULL);
WaitForSingleObject(m_hThread, 3000);
CloseHandle(m_hThread);
m_hThread = NULL;
}