您的位置:首页 > 产品设计 > UI/UE

用 QueueUserAPC() 函数来强制线程退出等待状态

2011-07-11 16:28 369 查看
当系统创建一个线程的时候,会同时创建一个与线程相关的队列。这个队列被成为异步过程调用(APC)队列。同时我们也知道,windows提供了6个函数可以等待并将线程设置为可提醒状态---------
SleepEx(),
WaitForSingleObjectEx(),
WaitForMultipleObjectsEx(),
SignalObjectAndWait(),
GetQueuedCompletionStatusEx(),
MsgWaitForMultipleObjectsEx()
当我们调用这6个函数之一并将线程设置为可提醒状态的时候,系统会首先检查线程的APC队列。如果队列中至少有一项,那么系统不会让线程进入睡眠状态。
需要牢记:当带调用这些函数的时候,只要线程的APC队列中至少有一项,线程就不会进入睡眠状态。

这个6个函数的返回值也是很重要的:如果是WAIT_IO_COMPLETION,那么我们就知道线程得以运行的原因是线程至少处理了APC中的一项。
windows提供了一个函数,允许我们手动的添加一项到指定线程的APC队列中:
DWORD WINAPI QueueUserAPC(
__in PAPCFUNC pfnAPC,
__in HANDLE hThread,
__in ULONG_PTR dwData
)

用这个函数,我们可以强制让线程退出等待状态,看代码:

// QueueUserAPC退出线程.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;

VOID WINAPI APCFunc(ULONG_PTR dwParam)
{
//do nothing
cout<<"APC函数"<<endl;
}

DWORD WINAPI ThreadFun(PVOID pvParam)
{
HANDLE hEvent  = (HANDLE)pvParam;

DWORD dw = WaitForSingleObjectEx(hEvent,INFINITE,TRUE);

if(dw == WAIT_OBJECT_0)
{
//如果事件被触发....
cout<<"事件触发"<<endl;
}

if(dw == WAIT_IO_COMPLETION)
{
//如果线程至少处理了APC队列中的一项
cout<<"处理了APC 项目"<<endl;
return 0;
}

cout<<"等待成功"<<endl;
return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
HANDLE hThread = (HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall *)(void *))ThreadFun,(PVOID)hEvent,0,NULL);
//执行一些其他代码

//此时用户想要终止子线程
Sleep(1000); //这里等待一秒很重要,因为最起码要留出时间先让子线程进入等待(可提醒)状态哦。
QueueUserAPC(APCFunc,hThread,NULL);
WaitForSingleObject(hThread,INFINITE);

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐