std:: notify_all_at_thread_exit
| 
 | 
 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 
           Defined in header
            
            
             <condition_variable>
            
            | ||
| 
           
            
             void
            
            notify_all_at_thread_exit
            
             (
            
            
             
              std::
              
               condition_variable
              
             
            
            
             &
            
            cond,
             std:: unique_lock < std:: mutex > lk ) ; | (since C++11) | |
       
        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 lk is transferred to internal storage.
- 
        The execution environment is modified such that when the current thread exits, the condition variable
        
         
          cond
         
        
        is notified as if by
        
         
          lk.
          
           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.
If any of the following conditions is satisfied, the behavior is undefined:
- lk is not locked by the calling thread.
- 
        If some other threads are also waiting on
        
         
          cond
         
        
        ,
        
         
          lk.
          
           mutex
          
          
           (
          
          
           )
          
         
        
        is different from the mutex unlocked by the waiting functions (
        wait, wait_for and wait_until ) called on cond by those threads.
Notes
An equivalent effect may be achieved with the facilities provided by std::promise or std::packaged_task .
       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.
      
In typical use cases, this function is the last thing called by a detached thread.
Parameters
| cond | - | the condition variable to notify at thread exit | 
| lk | - | the lock associated with the condition variable cond | 
Return value
(none)
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:
       
#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.
| DR | Applied to | Behavior as published | Correct behavior | 
|---|---|---|---|
| LWG 2140 | C++11 | the call to 
          notify_all_at_thread_exit
         synchronized with calls to functions waiting on cond | updated the synchronization requirement | 
See also
| sets the result to specific value while delivering the notification only at thread exit (public member function of 
           std::promise<R>
          ) | |
| executes the function ensuring that the result is ready only once the current thread exits (public member function of 
           std::packaged_task<R(Args...)>
          ) |