4 ms·
That would be relying on the OS to do the right thing. One problem is that on some platform or for some usage pattern, then mutex and notifying object will be t
by pierrebai 10y ago
That would be relying on the OS to do the right thing. One problem is that on some platform or for some usage pattern, then mutex and notifying object will be two independent objects, so the OS would have no way of knowing that it should not immediately wake up the notified threads.
Furthermore, it is a good rule of thumb anyway: hold the mutex for the shortest time possible. The corresponding pattern is to hold a mutex, copy the data you need to a local copy, release the mutex and then do the processing on the local copy. Sometimes, the processing can have unknown dependency and so it avoids potential deadlocks caused by some function called during processing trying to take a lock that is held be another thread.
Basically, never hold a lock while calling functions. You never know what might be hidden behind them now and will be hidden in the future.
- exDM69 10y ago> One problem is that on some platform or for some usage pattern, then mutex and notifying object will be two independent objects, so the OS would have no way of knowing that it should not immediately wake up the notified threads. On all significant platforms I know, condition wait works like this: condition_wait(locked_mutex, condition_to_wait); For each thread in the wait list, the condition variable "knows" which mutex it is holding. When signalling a waiting thread, it's added to the wait list of the mutex (if mutex is locked), not actually woken up. Did you have a platform in mind that works differently from this? Additionally, when you unlock a mutex before signalling the condition, another thread may be scheduled in between that may invalidate the condition that was signalled. This may introduce a race condition. I signal my condition variables with mutexes locked because it's easier to guarantee correctness that way.
- no-bugs 10y ago> Additionally, when you unlock a mutex before signalling the condition, another thread may be scheduled in between that may invalidate the condition that was signalled. This may introduce a race condition. And if you unlock the mutex after signalling the condition, another thread can be still scheduled in between the call to notify() and whatever-notified-thread-which-starts-to-run (and can still invalidate whatever-conditions-it-can-invalidate). There is absolutely no guarantee whatsoever that notified-thread gets to your mutex first (not that it really should matter for correctness in any sane program BTW). > I signal my condition variables with mutexes locked because it's easier to guarantee correctness that way. There is no difference in guarantees in practice whether you notify within or after; I'm not even sure that there is any difference in theory (exactly because the thread-which-was-notified is not guaranteed to get mutex first).
- gpderetta 10y agoThe optimization you are talking about is called wait morphing. Linux futexes have support for this optimization, and glibc pthread_cond_signal did support it at one point. I'm not sure wether they still do though. Unless you are writing hard realtime systems where you can make use of the strict scheduling guarantees of SCHED_FIFO, signaling while holding the lock is never necessary nor sufficient for correctness. The waiter must be checking the condition in a loop anyway.