std::notify...thread_exit(3)
π std::notify...thread_exit(3) π
okay bestie, this page is from the C++ Standard Libary (yes, that spelling, iykyk π), and it's all about std::notify_all_at_thread_exit. it's giving thread-exit realness, and honestly? kinda iconic β¨
πΈ NAME πΈ
std::notify_all_at_thread_exit β std::notify_all_at_thread_exit
that's the name, bestie. it's literally the same thing twice and i respect the consistency π«Ά
π¦ Synopsis π¦
Defined in header <condition_variable>
void notify_all_at_thread_exit( std::condition_variable& cond,
std::unique_lock<std::mutex> lk );
since C++11 β yes ma'am, this one has been around π
notify_all_at_thread_exit provides a mechanism to notify other threads that a given thread has completely finished, including destroying all thread_local objects. it operates as follows:
- Ownership of the previously acquired lock
lkis transferred to internal storage. yes, it takes the lock off your hands π - The execution environment is modified such that when the current thread exits, the condition variable
condis notified as if bylk.unlock(); cond.notify_all();.
The implied lk.unlock() is sequenced after the destruction of all objects with thread local storage duration associated with the current thread. so like, thread locals get destroyed first, then the unlock happens, then the notify. order matters, bestie π
β οΈ UB ALERT β if any of the following conditions is satisfied, the behavior is undefined: -lkis not locked by the calling thread. - If some other threads are also waiting oncond,lk.mutex()is different from the mutex unlocked by the waiting functions (wait,wait_forandwait_until) called oncondby those threads.
π§ Notes π§
An equivalent effect may be achieved with the facilities provided by std::promise or std::packaged_task. so like, there's more than one way to serve this look π
The supplied lock lk is held until the thread exits. Once this function has been called, no more threads may acquire the same lock in order to wait on cond. If some threads are waiting on this condition variable, ensure that the condition being waited for is satisfied while holding the lock on lk, and that this lock is not released and reacquired prior to calling notify_all_at_thread_exit to avoid confusion from spurious wakeups in other threads. no cap, spurious wakeups are messy and we do not want the confusion π
In typical use cases, this function is the last thing called by a detached thread. main character energy: last call, then exit β¨
π Parameters π
condβ the condition variable to notify at thread exit.lkβ the lock associated with the condition variablecond.
π Return value π
(none) β yep, it returns nothing. we love a void moment π
π Example π
This partial code fragment illustrates how notify_all_at_thread_exit can be used to avoid accessing data that depends on thread locals while those thread locals are in the process of being destructed:
// Run this code
#include <cassert>
#include <condition_variable>
#include <mutex>
#include <string>
#include <thread>
std::mutex m;
std::condition_variable cv;
bool ready = false;
std::string result; // some arbitrary type
void thread_func()
{
thread_local std::string thread_local_data = "42";
std::unique_lock<std::mutex> lk(m);
// assign a value to result using thread_local data
result = thread_local_data;
ready = true;
std::notify_all_at_thread_exit(cv, std::move(lk));
} // 1. destroy thread_locals;
// 2. unlock mutex;
// 3. notify cv.
int main()
{
std::thread t(thread_func);
t.detach();
// do other work
// ...
// wait for the detached thread
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{ return ready; });
// result is ready and thread_local destructors have finished, no UB
assert(result == "42");
}
π©Ή Defect reports π©Ή
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
LWG 2140β applied to C++11. Behavior as published: the call tonotify_all_at_thread_exitsynchronized with calls to functions waiting oncond. Correct behavior: updated the synchronization requirement. thank u for the fix, bestie π
π See also π
set_value_at_thread_exitβ sets the result to specific value while delivering the notification only at thread exit (public member function ofstd::promise<R>).make_ready_at_thread_exitβ executes the function ensuring that the result is ready only once the current thread exits (public member function ofstd::packaged_task<R(Args...)>).
xoxo, bestie π β this iconic page comes from http://cppreference.com, dated 2024.06.10, and it's literally std::notify...thread_exit(3) β¨π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms