我刚刚意识到我的APC被另一个线程打断了。 所以在这一点上我想知道这是怎么回事。 据我了解APC的概念:
所以这是我最初的情况:
我有一个多线程应用程序(1个主线程,1个接收线程)。
较低优先级的接收线程是从外部源接收数据。
使用WaitForSingleObject()
也可以重新激活接收线程。
收到的数据存储在共享的std::list
中。
主线程实际上没有任何效果。
每隔x毫秒发生一次特殊事件,导致接收线程调度APC。
此APC在主线程的上下文中运行。
所以这是一个整个情况的伪源代码示例。
class Example {
public:
Example(void) {
::DuplicatHandle(
::GetCurrentProcess(),
::GetCurrentThread(),
::GetCurrentProcess(),
&m_mainthreadHandle,
THREAD_SET_CONTEXT,
FALSE,
0);
}
void run(void) {
::WaitForSingleObjectEx(m_apcActivation);
}
protected:
private:
void rxThread(void) {
// this seems to be called during the apcRoutine() is running
// as result the shared list m_rxList is corrupted!
::WaitForSingleObject(m_externalActivation);
Data data = externalReceive();
if(data.attribute == SPECIAL) {
::QueueUserAPC(apcRoutine, m_mainthreadHandle, 0);
} else {
m_rxList.push_front(data);
}
}
void apcRoutine(void) {
while(!m_rxList.empty()) {
m_rxList.front().print();
m_rxList.pop_front();
}
}
std::list<Data> m_rxList;
HANDLE m_externalActivation;
HANDLE m_apcActivation;
HANDLE m_mainthreadHandle;
};
void main(void) {
Example e;
e.run();
}
我的问题是:
接收线程的WaitForSingleObject()
是否可能中断APC?
如果是,为什么?
答案 0 :(得分:5)
您似乎对APC存在一些误解。
有两种(实际上是三种)APC,用户模式和内核模式(具有两个不同的优先级)APC。
Usermode APC(例如您在代码中使用的APC)的行为与kernelmode APC的行为方式不同。特别是:
QueueUserAPC
时,它们不会立即运行,除非目标线程已在可警告的等待中被阻止。相反,APC 排队。NtTestAlert
时才会运行它们。NtAlertThread
,但它并不像人们期望的那样工作,NtAlertResumeThread
也没有。Kernelmode APC会抢占用户模式线程并且不会被它们中断(并且APC_LEVEL APC也不会被PASSIVE_LEVEL APC中断)。
<小时/> 1 如果情况确实如此,那将是非常荒谬的。这样,您可以使用APC完全破坏调度程序,消耗不确定的CPU时间 - 无论进程优先级,权限或配额如何。