APC机制

当系统创建一个线程的时候,会同时创建一个与线程相关的队列。这个队列被叫做异步过程调用(APC)队列。

为了对线程中的APC队列中的项进行处理,线程必须 将自己设置为可提醒状态,只不过意味着我们的线程在执行的时候已经到达了一个点,在这个点上它能够处理被中断的情况,下边的六个函数能将线程设置为可提醒状态:

BOOL SleepEx();
DWORD WaitForSingleObjectEx();
DWORD WaitForMultipleOBjectsEx();
BOOL SingalObjectAndWait();
BOOL GetQueuedCompletionStatusEx();   //这五个函数的最后一个参数是BOOL值,表示是否设置为可提醒状态。

DWORD MsgWaitForMultipleObjectsEx(); //最后一个参数设置为MWMO_ALERTABLE 标志

当我们调用上边的六个函数之一并将线程设置为可提醒状态的时候,系统首先会检查线程的APC队列,如果队列中至少有一项,那么系统就不会让线程进入睡眠状态。系统将会把那一项取出来并让线程执行与之相关的回调函数。当回调函数返回的时候,会再次检查APC队列中是否还有其他项,如果还有就继续处理,如果没有,对于可提醒函数的调用将会返回。这个是在前边APC中有一项的基础上。
但是当在刚调用函数时,线程的APC的队列中一项都没有,这些函数就会将线程挂起。挂起以后,如果调用了某个函数向该线程的APC队列中添加了一项,则线程将会被唤醒,执行队列中那一项相关联的回调函数后并将该项清除出队列,然后等待函数会立即返回。
微软为我们提供了一个函数,可以手动的将一项添加到线程的APC队列中。
DWORD QueueUserAPC(PAPCFUN pfnAPC,HANDLE hThread,ULONG_PTR dwParam);
pfnAPC:指向回调函数指针。函数原型必须是这个样子:VOID WINAPI APCFUN(ULONG_PTR dwParam);
hThread:线程的句柄,如果是另一个进程中的线程,那么pfnAPC函数内存地址也必须在另一个线程所在的地址空间中。
dwParam:传给回调函数的参数。

可以使用这进行非常高效的线程间的通信,但是只能传入一个值。

这个函数也可以强制让线程退出。加入等待函数正在等待一个内核对象,当这个内核对象还没有触发的时候我们可能要强终止线程或者进程,这样进行线程的强制退出是“干净的”线程退出。

eg:
假如现有一个主线程,主线程创建了一个子线程,子线程中调用了WaitForMultipleObjectEx()并将线程设置为可提醒状态,如果用户立马要终止应用程序:

VOID WINAPI APCFunc(ULONG_PTR dwParam)
{//Nothing To Do};

int WINAPI ThreadFunc(PVOID pvParam)
{
        DWORD dw=WaitForSingleObjectEx(hEvent,INFINITE,TRUE);
       if(dw==WAIT_OBJECT_0)  {}  //等待事件成功
       if(dw==WAIT_TO_COMPLETION) { return (0);}   //APC队列中有项,执行完APCFun之后执行到这个地方  return(0) 线程就会正常结束
       ..........
       return(0);
   }
VOID main()
{
        HADNLE hEvent=CreateEvent();
       HANDLE hThread=CreateThread(NULL,0,ThreadFunc,&hEvent,NULL,NULL);a
       QueueUserAPC(APCFunc,hThread,NULL);
       WaitForSingleObject(hThread,INFINITE);
       CloseHadle(hThread);
       CloseHandle(hEvent);
   }

当然创建另一个内核事件对象通过调用WaitForMultipleObjects()也可以终止线程,但是WaitForMultipleIbjects()在等待所有的对象都触发的时候,这个是唯一的线程退出的方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows APC(Asynchronous Procedure Call)是一种异步过程调用机制,它允许一个线程在另一个线程上异步执行指定的函数。APC 机制是 Windows 操作系统中非常重要的一部分,它被广泛用于实现各种系统功能,例如异步 I/O、线程池等。 在 Windows 中,每个线程都有一个 APC 队列,该队列中存储了需要在该线程上异步执行的函数。当一个线程进入 Alertable 状态时(例如调用 Sleep、WaitForSingleObject 等函数),它会检查自己的 APC 队列中是否有待处理的 APC,如果有,则会立即执行 APC 中指定的函数。 APC 机制的具体原理如下: 1. 创建 APC 对象 首先,创建一个 APC 对象,该对象包含要在目标线程上执行的函数和参数。 2. 将 APC 对象插入到目标线程APC 队列 使用 QueueUserAPC 函数将 APC 对象插入到目标线程APC 队列中。当目标线程进入 Alertable 状态时,它会检查自己的 APC 队列中是否有待处理的 APC,如果有,则会立即执行 APC 中指定的函数。 3. 触发目标线程进入 Alertable 状态 为了让目标线程进入 Alertable 状态,可以使用 Sleep、WaitForSingleObject 等函数来实现。当目标线程进入 Alertable 状态时,它会检查自己的 APC 队列中是否有待处理的 APC,如果有,则会立即执行 APC 中指定的函数。 总之,APC 机制是 Windows 操作系统中非常重要的一部分,它提供了一种有效的异步过程调用机制,可以在不阻塞目标线程的情况下异步执行指定的函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值