使用事件杀死线程的时间不一致
Posted
技术标签:
【中文标题】使用事件杀死线程的时间不一致【英文标题】:Timing inconsistency with killing thread using event 【发布时间】:2014-02-11 20:45:40 【问题描述】:我有一个多线程 C++ Windows 应用程序。工作线程是一个等待事件处理的无限循环,其中之一是来自主线程的终止线程事件。问题是有时工作线程需要很长时间(想想几秒钟)才能接收到 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 更改为某个合理的数字会解决此问题吗?
谢谢,
【问题讨论】:
没有什么明显的错误。如果您注释掉对doAction1()
和doAction2()
的调用,您还会看到延迟吗?
哦,您的活动会自动重置吗?如果是这样,请尝试手动重置。
唯一合理的解释是你所建议的 - 线程正在执行“doActionX”调用之一。
在设置事件终止线程之前,您可以尝试增加要终止线程的优先级。
@rcgldr 谢谢你的建议,我试试看。
【参考方案1】:
如果不是,您的 isWorkerThreadRunning 声明应该是 volatile 的。如果代码不是 volatile,编译器优化代码时可能会出现一些奇怪的行为。
volatile bool isWorkerThreadRunning;
我还建议在您的 doAction 函数中输入和退出消息。如果您在发送退出信号时仍在其中一个函数中,那将会更清楚。
【讨论】:
以上是关于使用事件杀死线程的时间不一致的主要内容,如果未能解决你的问题,请参考以下文章