问题:多个线程等待一个Event时,谁能获得激活信号?
测试结论:
1. 当时间设为人工Reset时,所有线程都能获得Event信号。(因为的测试的线程数量较少,可能在调用“人工”ResetEvent时,所有线程已获得信号,如果线程数量较多时,可能只有一部分才获得到.)
2. 设为自动Reset时,只有一个线程可以获得信号。
#define EVENT_NAME _T("TEST_EVENT_2018")
//线程数量
#define THREAD_NUM 5
//事件
HANDLE g_hEvent;
//临界区,获取线程执行结果的同步
CRITICAL_SECTION g_cs;
//线程句柄
HANDLE g_hThrd[THREAD_NUM];
//执行结果
CString g_strRun;
//析构
if (g_hEvent != NULL)
{
CloseHandle(g_hEvent);
g_hEvent = NULL;
}
DeleteCriticalSection(&g_cs);
// TODO: 在此添加额外的初始化代码
g_hEvent = CreateEvent(NULL, TRUE, FALSE, EVENT_NAME);
InitializeCriticalSection(&g_cs);
for (int i = 0; i < THREAD_NUM; ++i)
g_hThrd[i] = NULL;
SetTimer(1000, 100, NULL);
int ThreadFunc1(void* param)
{
int *pNo = reinterpret_cast<int *>(param);
CString strRun;
DWORD dwWaitTime = ((*pNo) * 2 + 10) * 1000;
DWORD dwWait = WaitForSingleObject(g_hEvent, dwWaitTime);
ResetEvent(g_hEvent);
if (dwWait == WAIT_OBJECT_0)
{
//timeout
strRun.Format(_T("Thread[%02d] get signal--"), (*pNo + 1));
}
else
{
//timeout或者其他错误
strRun.Format(_T("Thread[%02d] is timeout--"), (*pNo + 1));
}
EnterCriticalSection(&g_cs);
g_strRun += strRun;
LeaveCriticalSection(&g_cs);
delete pNo;
pNo = NULL;
return 0;
}
void CtestDlg::OnBnClickedBtnEvent()
{
g_strRun.Empty();
//创建多个线程
for (int i = 0; i < THREAD_NUM; ++i)
{
int *pNo = new int;
*pNo = i;
g_hThrd[i] = (HANDLE)_beginthreadex(0, 0, (unsigned int(__stdcall *)(void *))ThreadFunc1, pNo, 0, 0);
}
}
void CtestDlg::OnBnClickedBtnSetevent()
{
// TODO: 在此添加控件通知处理程序代码
if (g_hEvent != NULL)
SetEvent(g_hEvent);
}
void CtestDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nIDEvent == 1000 && g_hThrd[0] != NULL)
{
DWORD dwWait = WaitForMultipleObjects(THREAD_NUM, g_hThrd, TRUE, 1);
if (dwWait != WAIT_TIMEOUT)
{
for (int i = 0; i < THREAD_NUM; ++i)
{
CloseHandle(g_hThrd[i]);
g_hThrd[i] = NULL;
}
MessageBox(g_strRun);
}
}
CDialogEx::OnTimer(nIDEvent);
}
人工Reset:
自动Reset: