Timing inconsistency with killing thread using eve

2019-08-09 19:42发布

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

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.

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

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

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

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

Thanks,

1条回答
Emotional °昔
2楼-- · 2019-08-09 19:57

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;

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

查看更多
登录 后发表回答