我有一个多线程C ++ Windows应用程序。工作线程是一个无限循环,等待事件处理,其中一个是来自主线程的kill线程事件。问题是工作线程有时需要很长时间(想想秒)来接收kill事件并终止。其他时候它很快(毫秒)。
// Main thread code
void deactivate()
{
while (isWorkerThreadRunning)
{
// Problem: sometimes it spends a long time in this loop
logDebug("deactivate: killing worker thread");
SetEvent(killWorker);
Sleep(20);
}
}
// Worker thread code
DWORD WINAPI WorkerThreadProc(LPVOID arglist)
{
isWorkerThreadRunning = true;
logDebug("Worker thread started");
for (bool done = false; done != true; )
{
HANDLE handles[3] = { killWorker, action1, action2 };
DWORD rc = WaitForMultipleObjects(3, handles, FALSE, INFINITE);
switch (rc)
{
case WAIT_OBJECT_0 + 0: done = true; break;
case WAIT_OBJECT_0 + 1: doAction1(); break;
case WAIT_OBJECT_0 + 2: doAction2(); break;
default: logWarn("Unhandled wait signal");
}
}
isWorkerThreadRunning = false;
logDebug("Worker thread killed");
return 0;
}
我相信如果工作线程在doAction1()或doAction2()内部忙时收到kill事件,则直到doAction1()或doAction2()完成并返回后才会收到并处理kill事件。如果doAction1()或doAction2()需要很长时间才能返回,那么工作线程将需要很长时间才能退出。
但是,我在doAction1()和doAction2()中都有日志点,但我没有在日志文件中看到任何这些日志点。我所看到的只有:
deactivate: killing worker thread
deactivate: killing worker thread
deactivate: killing worker thread
deactivate: killing worker thread
//....many more times
Worker thead killed
这意味着工作线程没有做任何工作,而是等待WaitForMultipleObjects()调用。
问题是为什么WaitForMultipleObjects()调用有时需要很长时间(有时非常快)来向服务员发出事件信号?
将超时从INFINITE更改为某个合理的数字会修复此问题吗?
谢谢,
答案 0 :(得分:2)
如果不是,你的isWorkerThreadRunning声明应该是易变的。如果编译器在非易失性时优化代码,则可能会出现一些奇怪的行为。
volatile bool isWorkerThreadRunning;
我还建议在doAction函数中输入和退出消息。如果您在发送退出信号时仍然在其中一个功能中,这将使您更清楚。