function
<condition_variable>
std::notify_all_at_thread_exit
void notify_all_at_thread_exit (condition_variable& cond, unique_lock<mutex> lck);
Notify all at thread exit
When the calling thread exits, all threads waiting on cond are notified to resume execution.
The function also acquires ownership of the lock on the mutex object managed by lck, which is stored internally by the function and unlocked at thread exit (just before notifying all threads), behaving as if the following was called once all objects with thread storage duration have been destroyed:
1 2
|
lck.unlock();
cond.notify_all();
|
Parameters
- cond
- A condition_variable object to notify all at thread exit.
- lck
- A unique_lock object whose mutex object is currently locked by this thread.
The object is acquired by the function (it shall be an rvalue).
All waiting threads on cond (if any) shall use the same underlying mutex object as lck.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
// notify_all_at_thread_exit
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id (int id) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck);
// ...
std::cout << "thread " << id << '\n';
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
std::notify_all_at_thread_exit(cv,std::move(lck));
ready = true;
}
int main ()
{
std::thread threads[10];
// spawn 10 threads:
for (int i=0; i<10; ++i)
threads[i] = std::thread(print_id,i);
std::cout << "10 threads ready to race...\n";
std::thread(go).detach(); // go!
for (auto& th : threads) th.join();
return 0;
}
|
Possible output (order of threads may vary):
10 threads ready to race...
thread 9
thread 0
thread 7
thread 2
thread 5
thread 4
thread 6
thread 8
thread 3
thread 1
|
Data races
The function performs two atomic operations:
- Unlocking lck.
- Notifying all waiting threads for cond.
The destruction of the variables with thread-local storage is synchronized with the wake-up notifications in waiting threads.
Exception safety
Basic guarantee: if an exception is thrown, the objects passed as arguments are in a valid state.
It may throw system_error in case of failure (transmitting any error condition from unlock).