Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows SleepEx期间处理了多少APC?_Windows_Multithreading_Sleep - Fatal编程技术网

Windows SleepEx期间处理了多少APC?

Windows SleepEx期间处理了多少APC?,windows,multithreading,sleep,Windows,Multithreading,Sleep,这在某种程度上与我的一篇关于SleepEx实际工作原理的文章有关。假设执行SleepEx的线程在APC排队时恢复,并且当线程已经执行APC时,APC可能会继续排队 那么线程执行APCs的时间有多长?是否在每次选中队列时都是空的,并且此时SleepEx将控制权返回给调用者?或者该线程只执行了一个APC,那么SleepEx返回,APC的另一个执行需要再次调用SleepEx 我感觉APC会一直执行,直到队列第一次清空。谢谢 执行APC,直到队列为空。当您的代码从APC-系统检查返回时,是否插入了另一个

这在某种程度上与我的一篇关于
SleepEx
实际工作原理的文章有关。假设执行
SleepEx
的线程在APC排队时恢复,并且当线程已经执行APC时,APC可能会继续排队

那么线程执行APCs的时间有多长?是否在每次选中队列时都是空的,并且此时
SleepEx
将控制权返回给调用者?或者该线程只执行了一个APC,那么
SleepEx
返回,APC的另一个执行需要再次调用
SleepEx


我感觉APC会一直执行,直到队列第一次清空。谢谢

执行APC,直到队列为空。当您的代码从APC-系统检查返回时,是否插入了另一个APC-如果是,则执行下一个APC,直到不再在线程中插入APC。在此之后,
SleepEx
(或任何其他可报警的等待api)将控件返回给您


以下一种方式执行的APC—当您调用某些api(
SleepEx
MsgWaitForMultipleObjectsEx
WaitForSingleObjectEx
WaitForMultipleObjectsEx
。函数的bAlertable参数设置为TRUE)时,将APC插入到线程对象中。如果是-内核将用户模式线程上下文复制到它的堆栈中,然后更改线程上下文(用户模式返回地址设置为
ntdll.KiUserApcDispatcher
)并返回。结果代码不是从他进入内核的地方返回(如果
SleepEx
这是内部调用的
ZwDelayExecution
),而是返回到
KiUserApcDispatcher
。此api执行APC,然后调用
ZwContinue
。此api声明为:

NTSYSAPI NTSTATUS NTAPI ZwContinue(PCONTEXT Context, BOOLEAN TestAlert);

使用的就地上下文保存在堆栈线程上下文中,用于返回调用可报警api的点,并且
TestAlert
指定是否应检查是否插入了其他apc。如果使用
TestAlert==FALSE调用
ZwContinue
,系统将不再检查线程队列中的APC,直到您自己不调用
SleepEx
或其他特定api为止-因此将执行1个APC。但是在
KiUserApcDispatcher
TestAlert
硬编码为
TRUE
-如果您理解汇编代码(KiUserApcDispatcher
很小)

它是不可知的,那么您可以自己查看它。调用QueueUserApc()的线程不知道可警报线程是否已恢复。可警报线程在恢复之前是否在队列中工作不再重要。@HansPassant我的问题不是从QueueUserApc的角度,而是SleepEx如何工作。@HansPassant-你错了。这可能是未记录的,但确切地说是已知的——当线程从APC返回时——系统检查是否在线程中插入了额外的APC。如果是,执行它。所以这将在循环中,直到不再有APC在threadHmya中,我并没有说是或否,我说这不重要。任何一个认为这很重要的人几乎肯定都在酝酿一个他们无法修复的线程竞赛错误。只是认识到问题中使用了“多少”是因为它很短,“1”可能是一个有效的答案,甚至“15”可能是硬编码的。我不在乎一个可以依赖的实际数字,在我看来,这个问题的主体非常清楚地表明了这一点。在主题中问“多长时间…”并不意味着我想知道秒或分钟或其他什么。这是绝对正确的,但我认为Hans也是对的:如果你的代码依赖于这种行为,你很可能做错了什么。(可能有边缘案例。)@HarryJohnston-是的,同意。但我只是对问题的正式回答。解释apc是如何工作的