Search code examples
c++multithreadingloopsc++11stdthread

Start and Stop a loop within a Thread in C++


I need to start a loop from an event and then stop it from another event. My idea was to call the function startDequeuing() when I press the button so that a thread with the loop start and then to terminate this loop putting "dequeuing" variable at false from the function stopDequeuing().

It's the first time I use thread, the program locks when I start the loop I think because the variable 'dequeuing' is locked and inaccessible from outside the thread, am I correct?

How can I solve this problem??

Here there is some code:

void CameraManager::startDequeuing(){
    dequeuing = true;
    std::thread dequeueThread(&CameraManager::dequeueLoop, this);
    dequeueThread.join();
}

void CameraManager::stopDequeuing(){
    dequeuing = false;
}

void *CameraManager::dequeueLoop(){
    while(dequeuing){
        highSpeedCamera->dequeue();
        highSpeedCamera->enqueue();
    }
}

Solution

  • The whole point of using threads is to get more than one function running in parallel. Here:

    std::thread dequeueThread(&CameraManager::dequeueLoop, this);
    dequeueThread.join();
    

    You start a second thread and put the first thread to sleep, waiting for the spawned thread to return. So you still have just one thread running. If you have so kind of GUI event loop, you might lock for a possibility to add a callback that will get called, when ever that event loop is empty. This might enable you to do what you want without using threads at all.

    A solution might look like this:

    void CameraManager::startDequeuing(){
        dequeuing = true;
        dequeueThread = std::thread(&CameraManager::dequeueLoop, this);
    }
    
    void CameraManager::stopDequeuing(){
        {
            std::lock_guard<std::mutex> lock( mutex );
            dequeuing = false;
        }
        dequeueThread.join();
    }
    
    bool CameraManager::keepOnDequeuing()
    {
        std::lock_guard<std::mutex> lock( mutex );
        return dequeuing;
    }
    
    void *CameraManager::dequeueLoop(){
        while( keepOnDequeuing() ){
            highSpeedCamera->dequeue();
            highSpeedCamera->enqueue();
        }
    }