lundi 25 juin 2018

std thread synchronization object without a mutex in modern modern C++?

I implemented a simple thread 'exit' synchronization:

void  CMyThread::Run() // Worker Thread
{
    while (m_bRunning)
    {
        // Wait for something to happen ('Stop()' or something else (5 sec. watchdog):
        m_wake_up.wait_for(guard, std::chrono::seconds(5)); // <-- No need for a mutex
        .
        . (do something with m_pMessageQueue)
        .
        if (!m_bRunning) // The right point to exit; no use of m_pMessageQueue
        {
            m_pMessageQueue = nullptr;
            m_stopped.notify_one(); // CMyThread::Stop() is on m_stopped.wait_for(...)
            TRACE("Router-thread stopped. Main-thread notified.\n");
        }
    }
}

The GUI thread calls Stop() to stop the worker thread:

    void  CMyThread::Stop() // <-- Called by GUI thread
    {
        std::mutex m_dummy_mutex;
        std::unique_lock<std::mutex> guard(m_dummy_mutex); // <-- No need for mutex


        TRACE("CMyThread state switched to not-running.\n");
        m_bRunning = false;
        Notify(); // For the case of MyThread is during m_wake_up.wait_for()

        TRACE("Wait for CMyThread stopped notification...\n");
        bool rv = m_stopped.wait_for(guard, std::chrono::seconds(5), [this]() {return (m_pMessageQueue == nullptr); });
            // Before sleep, unlock 'guard'; on granted, lock it again. Mitigate spurious wakeup. 

        #ifdef _DEBUG
        if (rv)
            TRACE("CMyThread stopped notification - Received.\n");
        else
            TRACE("CMyThread stopped notification - Timeout expired.\n");
        #endif
    }

And wait (up to 5 seconds) to the worker-thread to exit. BUT, apparently, there is no need for a mutex in any of the 2 functions. What is, in Modern c++, the mechanism of such a wait_for() without using any mutex?

Aucun commentaire:

Enregistrer un commentaire