SleepEx和QueueUserAPC的有关问题
SleepEx和QueueUserAPC的问题
------解决方案--------------------
#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 !
- 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 !