SleepEx和QueueUserAPC的有关问题

SleepEx和QueueUserAPC的问题
C/C++ code

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <assert.h>

VOID CALLBACK APCProc1(LONG_PTR dwParam)
{
    TCHAR* pStr = (TCHAR*)dwParam;
    MessageBox(NULL,pStr,TEXT("APCProc1"),MB_OK);
}

VOID CALLBACK APCProc2(LONG_PTR dwParam)
{
    TCHAR* pStr = (TCHAR*)dwParam;
    MessageBox(NULL,pStr,TEXT("APCProc2"),MB_OK);
}

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    SleepEx(INFINITE,TRUE);   
         printf("%s\n","Child thread exit !");
    return 0;
}

int main()
{
    HANDLE hThread = CreateThread(NULL,
        0,
        (LPTHREAD_START_ROUTINE)ThreadProc,
        NULL,
        0,
        NULL);

    assert(hThread != NULL);
    
    TCHAR* p1 = "JMF";
    TCHAR* p2 = "ni hao !";
    QueueUserAPC((PAPCFUNC)APCProc1,hThread,(ULONG_PTR)p1);
    QueueUserAPC((PAPCFUNC)APCProc2,hThread,(ULONG_PTR)p2);
    WaitForSingleObject(hThread,INFINITE);
    return 0;
}

MSDN SleepEx返回的三种情况:
1>超时
2>IO完成例程被调用
3>APC被投递到线程队列

为什么我这儿的创建的线程始终不退出啊?  不明白,请牛人指点 



------解决方案--------------------
#4很有意思~~~ HD单传? 呵呵 开个玩笑

简单看了下楼主这个程序
从逻辑上来说确实应该可以退出(在两个APC之后SleepEx会由于APC的原因返回,然后主线程的WaitForSingleObject就会成功 然后程序结束。

但是看了一下发现楼主忽略了时间问题。
CreateThread是一个很耗时的事情,而且创建完以后并不意味着就直接开始运行。所以实际上楼主的程序流程变成了:
1、创建线程
2、插入APC
3、调度到ThreadProc
4、ThreadProc先执行两个APC,然后SleepEx
于是死锁。

解决方法是在QueueUserAPC之前Sleep一段时间(比如1秒)

代码修改后如下:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <assert.h>

VOID CALLBACK APCProc1(LONG_PTR dwParam)
{
TCHAR* pStr = (TCHAR*)dwParam;
MessageBox(NULL,pStr,TEXT("APCProc1"),MB_OK);
}

VOID CALLBACK APCProc2(LONG_PTR dwParam)
{
TCHAR* pStr = (TCHAR*)dwParam;
MessageBox(NULL,pStr,TEXT("APCProc2"),MB_OK);
}

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
SleepEx(INFINITE,TRUE);
printf("%s\n","Child thread exit !");
return 0;
}

int main()
{
HANDLE hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadProc,
NULL,
0,
NULL);

assert(hThread != NULL);

TCHAR* p1 = TEXT("JMF"); // 我这边是UNICODE的,楼主忘记TEXT宏结果我这边编译不通过 小修改下。
TCHAR* p2 = TEXT("ni hao !");
Sleep(1000); // <--------- here
QueueUserAPC((PAPCFUNC)APCProc1,hThread,(ULONG_PTR)p1);
QueueUserAPC((PAPCFUNC)APCProc2,hThread,(ULONG_PTR)p2);
WaitForSingleObject(hThread,INFINITE);
return 0;
}


运行结果:
H:\jkhjhj\Debug>jkhjhj.exe
Child thread exit !