====== 2015-12-13 - condition variable and lock ====== some time ago i was asked to make a code review of a multi-threaded code part. i found a code block like this: std::condition_variable cv; std::mutex m; // ...a lot of code here... std::unique_lock lock(m); cv.notify_one(); and commented it as a "no-no" -- why to notify, while still having mutex locked?! it's obvious other thread will do something like this: std::unique_lock lock(m); cv.wait(lock, someConditionCheck); // ... now process so it means we're waking up a thread, just so it can block on mutex, then we unlock and wake it up again, so that it can process. sounds like a waste, doesn't it? well -- it appears it does not work that way. in fact [[https://computing.llnl.gov/tutorials/pthreads/man/pthread_cond_signal.txt|POSIX advises signaling under a lock]]. dunno what are implementation details here, but doing this: m.lock(); // ... cv.notify_one(); m.unlock(); performs better than this: m.lock() // ... m.unlock(); cv.notify_one(); which was quite surprising for me. in fact the gain for linux system was ~3-10% (depending on the particular run and the machine test were run on), while at my friend's windows platform difference was as high as 30% ({{:blog:2015:12:13:condition_variable_and_lock.cpp|reference implementation}})! even though i still do not know why it is so, the good news is that naturally written [[wp>RAII]] code: std::lock_guard lock(m); // ... cv.notify_one(); works as expected and is superior, when it comes to performance.