计时与使用事件的线程不一致 [英] Timing inconsistency with killing thread using event

查看:125
本文介绍了计时与使用事件的线程不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多线程C ++ Windows应用程序。工作线程是一个无限循环,等待事件处理,其中一个是来自主线程的kill线程事件。问题是,有时需要一个很长的时间(想秒)工作线程接收kill事件并终止。其他时间很快(毫秒)。

I have a multithreaded C++ Windows application. The worker thread is an infinite loop waiting for events to process, one of which is a kill thread event from main thread. The problem is that sometimes it takes a really long time (think seconds) for the worker thread to receive the kill event and terminate. Other times it's very quick (milliseconds).

// 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;
}

我相信如果工作线程在内部忙时收到kill事件doAction1()或doAction2()kill事件将不会被接收和处理,直到doAction1()或doAction2()完成并返回。如果doAction1()或doAction2()需要很长时间才能返回,则工作线程将需要很长时间才能退出。

I believe that if the worker thread receives a kill event while it is busy inside doAction1() or doAction2() the kill event won't be received and processed until doAction1() or doAction2() is completed and returned. And if doAction1() or doAction2() takes a long time to return then the worker thread will take a long time to exit.

但是, doAction1()和doAction2(),但我没有看到日志文件中的任何日志点。我所看到的是:

However, I have log points sprinkled throughout doAction1() and doAction2() but I don't see any of those log points in the log file. All I see are:

deactivate: killing worker thread
deactivate: killing worker thread
deactivate: killing worker thread
deactivate: killing worker thread
//....many more times
Worker thead killed

这意味着工作线程不在做任何工作,而是在WaitForMultipleObjects()调用内部等待。

which means the worker thread is not doing any work but rather waiting inside the WaitForMultipleObjects() call.

问题是为什么WaitForMultipleObjects()调用有时需要很长时间(有时很快)发信号通知事件的服务员

The question is why is the WaitForMultipleObjects() call sometimes take a long time (and sometimes very quick) to signal the waiter of an event??

将超时从INFINITE更改为某个合理的数字解决这个问题?

Would changing the timeout from INFINITE to some reasonable number fix this problem?

感谢,

推荐答案

您的isWorkerThreadRunning声明应该是volatile不是这样。如果代码不易变,编译器会优化代码,你可能会得到一些奇怪的行为。

Your declaration of isWorkerThreadRunning should be volatile if it is not. You can get some strange behavior when the compiler optimizes the code if it is not volatile.

volatile bool isWorkerThreadRunning;

我还建议在doAction函数中输入和退出消息。这将使它更清楚如果你仍然在那些功能之一,当退出信号发送。

I would also suggest entry and exit messages in your doAction functions. That will make it clearer if your still inside one of those functions when the exit signal is sent.

这篇关于计时与使用事件的线程不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆