c++ - Notifying a consumer thread before or after releasing the lock on the mutex? -


below listing 4.5 book c++ concurrency in action defines thread-safe queue using condition variables.

#include <mutex> #include <condition_variable> #include <queue> #include <memory>  template<typename t> class threadsafe_queue { private:     mutable std::mutex mut;     std::queue<t> data_queue;     std::condition_variable data_cond; public:     threadsafe_queue()     {}     threadsafe_queue(threadsafe_queue const& other)     {         std::lock_guard<std::mutex> lk(other.mut);         data_queue=other.data_queue;     }      void push(t new_value)     {         std::lock_guard<std::mutex> lk(mut);         data_queue.push(new_value);         data_cond.notify_one();     }      void wait_and_pop(t& value)     {         std::unique_lock<std::mutex> lk(mut);         data_cond.wait(lk,[this]{return !data_queue.empty();});         value=data_queue.front();         data_queue.pop();     }  std::shared_ptr<t> wait_and_pop() {     std::unique_lock<std::mutex> lk(mut);     data_cond.wait(lk,[this]{return !data_queue.empty();});     std::shared_ptr<t> res(std::make_shared<t>(data_queue.front()));     data_queue.pop();     return res; }  bool try_pop(t& value) {     std::lock_guard<std::mutex> lk(mut);     if(data_queue.empty)         return false;     value=data_queue.front();     data_queue.pop(); }  std::shared_ptr<t> try_pop() {     std::lock_guard<std::mutex> lk(mut);     if(data_queue.empty())         return std::shared_ptr<t>();     std::shared_ptr<t> res(std::make_shared<t>(data_queue.front()));     data_queue.pop();     return res; }  bool empty() const {     std::lock_guard<std::mutex> lk(mut);     return data_queue.empty(); } };  int main() {} 

in push function, thread being notified while mutex still locked. isn't better notify popper threads right after mutex released. example, this:

void push(t new_value) {     {         std::lock_guard<std::mutex> lk(mut)         data_queue.push(new_value);     }     data_cond.notify_one(); } 

i aware functionally same thing. i'm thinking in original case, consumer thread receive false notification makes try locking mutex more once. however, in second case, avoid waking consumer thread early, , therefore, tries lock mutex can successful in first time.

that not matter, end result going same. if first notify , unlock mutex, listening thread notified, still locked on mutex, once mutex unlocked, thread proceed.

if first unlock mutex, thread not know condition ready until notified , waiting on condition variable (barred spurious wake ups).

in end, listening thread proceed once both conditions met - mutex unlocked, variable notified.


Comments

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -

windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -