何时使用QueueUserAPC()?

何时使用QueueUserAPC()?,c,multithreading,winapi,C,Multithreading,Winapi,我确实了解APC是什么,它是如何工作的,以及Windows是如何使用它的,但我不知道我(作为一名程序员)什么时候应该使用它,而不是光纤线程或线程池线程 我应该在什么时候选择使用QueueUserAPC,为什么?QueueUserAPC是一个整洁的工具,通常可以作为一些任务的快捷方式,而这些任务是通过同步对象处理的。它允许您在某个线程方便的时候(即,当它完成当前工作并开始等待某个任务时),告诉该线程执行某个任务 假设您有一个主线程和一个工作线程。工作线程打开文件服务器的套接字,并通过在循环中调用r

我确实了解APC是什么,它是如何工作的,以及Windows是如何使用它的,但我不知道我(作为一名程序员)什么时候应该使用它,而不是光纤线程或线程池线程


我应该在什么时候选择使用
QueueUserAPC
,为什么?

QueueUserAPC
是一个整洁的工具,通常可以作为一些任务的快捷方式,而这些任务是通过同步对象处理的。它允许您在某个线程方便的时候(即,当它完成当前工作并开始等待某个任务时),告诉该线程执行某个任务

假设您有一个主线程和一个工作线程。工作线程打开文件服务器的套接字,并通过在循环中调用recv()开始下载10GB文件。主线程希望工作线程在等待网络数据包时在其停机时间内执行其他操作;它可以将要在工作进程上运行的函数排入队列,否则它将等待并不执行任何操作

您必须小心使用APCs,因为在我提到的场景中,您不希望进行另一个阻塞WinSock调用(这将导致未定义的行为)。为了找到这个功能的任何好的用途,你真的必须关注它,因为你可以用其他方式做同样的事情。例如,让另一个线程在每次事件即将进入睡眠状态时检查它,而不是在等待时给它一个运行的函数。显然,在这种情况下,APC会更简单

这就像当你有一个呼叫台的员工坐在那里等电话,你在他们休息的时候给他们一些小任务去做。“在这里,在你等待的时候解决这个魔方。”虽然,当电话进来时,这个人不会放下魔方来接电话(APC必须在线程返回等待之前返回)


QueueUserAPC
如果有一个线程(线程a)负责某些数据结构,并且您希望从另一个线程(线程B)对该数据结构执行某些操作,但是您不希望有在两个线程之间共享该数据的同步开销/复杂性,那么它也很有用。通过让线程B将要在线程A上运行的操作排队(线程A单独维护该结构),您就可以在该数据上执行任意函数,而不必担心同步问题


它只是另一个类似于线程池的工具。但是,如果使用线程池,则无法将任务发送到特定线程。你无法控制工作在哪里完成。当您对任务排队时,可能会创建一个全新的线程。您可以将两个任务排队,并且它们可以在两个不同的线程上同时完成。使用
QueueUserAPC
,您可以保证任务将按顺序在指定的线程上完成。

这是Windows消息循环的低级等价物。它允许您以安全的方式将代码注入线程。线程通过执行一个可报警的等待来表示它准备好处理重入。就像调用GetMessage()。@HansPassant:Hmmm。。。我想是的,但我不太明白它是什么样子的GetMessage()。GetMessage只是检索一条消息,而QueueUserAPC调用该方法——因此它可能导致堆栈溢出,对吗?他们似乎不同…只是想记住每个人,“GetMessage”不是一个可提醒的等待。并且@Mehrdad,在线程准备好处理它们之前,没有QueueUserAPC将不会调用该方法,这在源代码中总是显式的code@Lothar:哇,整整四年后:)我不明白你说的和我所说的堆栈溢出有什么关系……堆栈溢出现在是一个知识库。作为一个问答网站,它目前失败得很厉害。但这是搜索APC时最重要的答案之一。所以我想我们可以继续评论。正常的消息循环是人们在使用APC时遇到的第一个陷阱之一,这是基于这里和其他论坛的问题。