Search code examples
c++multithreadingc++14condition-variable

How to use wait_for in a looping thread?


I want to have a thread (std::thread) that does its work every 60 seconds, otherwise sleeps and instantly returns if the outside requests it. std::jthread is not an option, I'm limited to C++14.

std::condition_variable cv;

//Thread1:
void ThreadWork
{
    while(cv.wait_for(someLock, 60s) == std::cv_status_timeout)
    {
        Work();
    }
    return;
}

//Thread2:
void RequestEnd()
{
    cv.notify_one();
}

The idea here is that if the return val is std::cv_status_timeout, 60s have passed and we do the work normally. Otherwise, return.

Currently, I get some complaints from the runtime about the lock, or just straight up std::terminate.

Doing some tricks with a loop checking for an atomic variable is not what I want; this is about the thread sleeping.

Am I going in the right direction, at least?


Solution

  • std::future<void> seems to do the trick.

    // Worker thread setup
    void Work(std::future<void> killSwitch)
    {
        while(killSwitch.wait_for(60s) == std::future_status::timeout)
        {
            // ... Stuff
        }
    }
    
    // Controller thread
    std::promise<void> killSwitch;
    std::thread worker{ Work, std::move(killSwitch.get_future()) };
    
    // ... Stuff
    
    killSwitch.set_value(); // <-- this will break the loop
    worker.join();
    
    

    No mutexes, condition variables, spurious wakes, locks or atomics.