请看我写的例子程序:
const int THREAD_CNT = 1;HANDLE g_evt= NULL;
HANDLE g_evtArr[THREAD_CNT];CRITICAL_SECTION cs;unsigned WINAPI ThreadProc(LPVOID lpParam)
{
static long g_cnt = 0;
InterlockedIncrement(&g_cnt); int index = (int)lpParam; DWORD dwWaitResult = WaitForSingleObjectEx(g_evtArr[index], INFINITE, TRUE); EnterCriticalSection(&cs);
if (dwWaitResult == WAIT_IO_COMPLETION)
cout << "Thread Spawned " << (int)index << " IO Completed." << endl; 
LeaveCriticalSection(&cs); if (g_cnt == THREAD_CNT)
SetEvent(g_evt); return 0;
}void WINAPI APCEntry(DWORD uParam)
{

}
int main()
{
HANDLE threads[THREAD_CNT];
g_evt = CreateEvent(NULL, TRUE, FALSE, NULL);
InitializeCriticalSection(&cs);

unsigned threadid;
int i;
for (i= 0; i < THREAD_CNT; i++) {
g_evtArr[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
threads[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, (void *)i, 0, &threadid);
}
//Sleep(5); for (i= 0; i < THREAD_CNT; i++) {
    int j = QueueUserAPC(APCEntry, threads[i], i);
} WaitForSingleObject(g_evt, INFINITE);
DeleteCriticalSection(&cs);

return 0;
}我发现QueueUserAPC运行后,工作线程并没有退出,还是阻塞在WaitForSingleObjectEx处,加上Sleep(5),就可以了。我看MSDN里面说APC是可以Queue在线程的APC队列的,即使QueueUserAPC时工作线程没有处在alertable的状态,那它总会去执行APC队列里的请求啊,为什么阻塞住了呢,望各位大侠帮帮忙。

解决方案 »

  1.   

    呵呵你的主程序跑太快了。你可以仔细读一下MSDN,
    "If an application queues an APC before the thread begins running, the thread begins by calling the APC function. ”你主程序在QueueUserAPC的时候,你的新Thread还没有来得及开始,这种情况下系统会先清理光你的APC Queue,然后才开始执行你的ThreadProc,当然到了WaitForSingleObjectEx的时候,已经没有东西了,只能死等。你可以自己做个试验,在ThreadProc开始的时候加一个:MessageBoxW(0, L"start thread proc", L"here",0);然后在APCEntry里面放另外一个MessageBox,看看谁先跑出来就明白了。 加了Sleep(5),Thread就会先到Wait那里去等,自然没有问题了。