用 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
)
用这个函数,我们可以强制让线程退出等待状态,看代码:
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; }
相关文章推荐
- QueueUserAPC()强制线程退出等待状态
- 关于主线程等待子线程退出状态的判断函数的使用说明
- MFC 主线程等待子线程退出函数
- linux 线程等待与退出 pthread_join pthread_exit 函数
- socket编程中send函数引发的线程退出
- Windows系统下等待线程退出的方法
- Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)
- 对话框中WaitForSingleObject等待线程退出导致程序阻塞的原因及解决
- 理解 Thread.Sleep 函数 ,Sleep(0) 释放当前线程所剩余的时间片,让线程马上回到就绪队列而非等待队列
- 线程进入等待状态有几种方式?
- 兆鹏带你读Watir——【第二篇】浏览器状态及线程等待
- 异常信息:CLR无法从COM 上下文0x645e18 转换为COM上下文0x645f88,这种状态已持续60秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作.这种情况通常会影响到性能,甚至可能导致应用程序不响应或者使用的内存随时间不断累积
- 线程等待,退出
- 对话框中WaitForSingleObject等待线程退出导致程序阻塞的原因及解决
- 非阻塞TCP套接字的要点 发表于 2015-04-22 | 分类于 网络编程 | 套接字的默认状态是阻塞的。如果一个套接字不能立即完成相应的调用,那么该线程就会被投入睡眠,等待相应的操
- 等待线程退出 MsgWaitForMultipleObjects和WaitForSingleObject
- Java父线程(或是主线程)等待所有子线程退出
- MFC 主界面函数中线程等待避免界面卡死的处理方法
- MFC 主界面函数中线程等待避免界面卡死的处理方法
- C# 给某个方法设定执行超时时间 C#如何控制方法的执行时间,超时则强制退出方法执行 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)