Savoga

Condition Variable


A condition variable can be used to communicate between 2 threads. It always has to be associated with a mutex.

Essentially, it:

  • unlocks the mutex while waiting for a notification

  • re-locks the mutex after being notified


// Case 1: no condition variable
// => no communication between threads my_thread and main
int main() {
    auto start = std::chrono::high_resolution_clock::now();
    std::thread my_thread([&]{ 
        std::this_thread::sleep_for(std::chrono::seconds(3));
    });
    std::cout << "No wait." << std::endl;
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double, std::milli> elapsed = end - start;
    std::cout << "Elapsed time: " << elapsed.count() << " ms\n"; 
    // "No wait." arrives after few milliseconds only (no waiting)
    my_thread.join();
    return 0;
}

// Case 2: use of a condition variable
// => the main thread waits until a condition is reached in my_thread
int main() {
    std::mutex mtx;
    std::condition_variable cv;
    bool done = false;
    auto start = std::chrono::high_resolution_clock::now();
    std::thread my_thread([&]{ 
        std::this_thread::sleep_for(std::chrono::seconds(3));
        {
            std::lock_guard<std:: mutex> lock(mtx);
            done = true;
        }
        cv.notify_one();
    });

    {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [&]() { return done; });
    }
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double, std::milli> elapsed = end - start;
    std::cout << "Elapsed time: " << elapsed.count() << " ms\n"; 
    // "Wait." arrives after 3 seconds (after being notified)
    std::cout << "Wait." << std::endl;
    my_thread.join();
    return 0;
}