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

trying to understand condition variables


I have read about condition variables to signal between two or more threads. Now I am trying to understand some code I have. I have (simplified):

class Class{
    void put(Something&& something){
        {
            std::lock_guard<std::mutex> lock(a_mutex);
            // Do the operation here
            some_operation();
        }
        cond_var.notify_one();
    }
    
    std::unique_ptr<Something> get(){
        std::unique_lock<std::mutex> lock(a_mutex);
   
        cond_var.wait(lock,[this]{return someCondition()});
    
        //Do the operation here
        auto res=some_other_operation();
        return res;
    }
    
    std::mutex a_mutex;
    std::condition_variable cond_var;    
};

I can understand that put acquires a lock and do some operation and then notifies any thread waiting to unblock. Also get blocks until the condition variable gets signaled by put or it blocks if someCondition is not true. Once it gets signaled it do some other operation and returns its value.

What I don't understand is the timing.

For example let's say that the put function is called and it notifies but no thread is waiting because get has not been called. What happens?

Then let's say get gets called and it blocks. Or it doesn't? (ideally it shouldn't because someone already called put first).

Should get wait until put is called again?


Solution

  • For example let's say that the put function is called and it notifies but no thread is waiting because get has not been called. What happens?

    docs says: *If any threads are waiting on this, calling notify_one unblocks one of the waiting threads. If any, then if no nothing special happens.

    Then let's say get gets called and it blocks. Or it doesn't?? (ideally it shouldn't because someone already called put first).

    It will be blocked conditionally to someCondition(). If someOperation() leads to someCondition() being realized then wait will be unblocked when notify_one() will be called, or not blocked at all if someCondition() is already realized.