为何std::condition_variable.wait()发生异常时未重新加锁?
std::condition_variable::wait(): Exceptions and Lock Reacquisition Great question! Let's unpack this behavior and figure out why you might be seeing something that seems to contradict the documentation.
First, let's restate the standard behavior clearly, as per C++ specifications:
Whether a thread is woken by a notification, a spurious wakeup, or exits via an exception (in C14 and earlier),
wait()is required to reacquire the passedunique_lockbefore returning. C14 just clarified this rule more explicitly, but the intent was consistent in earlier versions.
If you're encountering cases where the lock isn't reacquired during an exception exit, here are the most likely explanations:
1. The exception comes from your predicate, not wait() itself
If you're using the predicate overload wait(lk, pred), the underlying logic looks roughly like this pseudocode:
while (!pred()) { wait(lk); }
If your pred() function throws an exception, that exception propagates directly to your caller—and at that point, wait() has already woken up and reacquired the lock. The lock is held when the exception is thrown, but if you're not handling the predicate's exceptions properly, you might mistakenly think the lock wasn't reacquired.
2. You're dealing with platform-specific thread termination (not standard C++ exceptions)
The C++ standard doesn't define thread cancellation mechanisms like POSIX's pthread_cancel. If your thread is terminated using one of these platform-specific tools, the behavior of wait() is undefined. It won't follow the standard's rule to reacquire the lock, and you could end up with the lock in an inconsistent state. This isn't a failure of standard behavior—it's using a feature outside what C++ specifies.
3. You're misunderstanding what counts as an "exception exit" from wait()
In standard C++, wait() itself doesn't throw exceptions under normal circumstances. The only time it can throw is when reacquiring the lock (e.g., if unique_lock::lock() throws, which is extremely rare and usually only happens if the mutex is in a broken state). In this case, the standard mandates that wait() must attempt to reacquire the lock before exiting—even if that attempt throws an exception.
4. You're using a non-conforming or outdated compiler implementation
While major compilers (GCC, Clang, MSVC) strictly follow the C++ standard, some older or niche compilers might have bugs that break the lock reacquisition rule during exceptions. If you suspect this, try upgrading to the latest version of your compiler—chances are the bug has been fixed.
To sum up: In standard C++ exception scenarios (like exceptions thrown during lock reacquisition), wait() will always reacquire the lock before exiting. If you're seeing something different, it's almost certainly one of the non-standard scenarios or code logic issues outlined above.
内容的提问来源于stack exchange,提问作者xmllmx

