std:: notify_all_at_thread_exit
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Определено в заголовочном файле
<condition_variable>
|
||
|
void
notify_all_at_thread_exit
(
std::
condition_variable
&
cond,
std:: unique_lock < std:: mutex > lk ) ; |
(начиная с C++11) | |
notify_all_at_thread_exit
предоставляет механизм для уведомления других потоков о том, что данный поток полностью завершил работу, включая уничтожение всех
thread_local
объектов. Он работает следующим образом:
- Владение ранее полученной блокировкой lk передается во внутреннее хранилище.
-
Среда выполнения модифицируется таким образом, что при завершении текущего потока условная переменная
cond
уведомляется как если бы было выполнено
lk.
unlock
(
)
;
cond. notify_all ( ) ; .
Подразумеваемый lk. unlock ( ) выполняется после упорядочивания разрушения всех объектов с продолжительностью хранения в локальной памяти потока , связанных с текущим потоком.
Если выполняется любое из следующих условий, поведение не определено:
- lk не заблокирован вызывающим потоком.
-
Если другие потоки также ожидают на
cond
,
lk.
mutex
(
)
отличается от мьютекса, разблокированного функциями ожидания (
wait, wait_for и wait_until ), вызванными на cond этими потоками.
Содержание |
Примечания
Эквивалентный эффект может быть достигнут с помощью средств, предоставляемых std::promise или std::packaged_task .
Предоставленная блокировка
lk
удерживается до завершения потока. После вызова этой функции никакие другие потоки не могут получить ту же блокировку для ожидания на
cond
. Если некоторые потоки ожидают на этой переменной условия, убедитесь, что условие, которого они ожидают, выполняется при удержании блокировки на
lk
, и что эта блокировка не освобождается и повторно не приобретается перед вызовом
notify_all_at_thread_exit
во избежание путаницы из-за ложных пробуждений в других потоках.
В типичных сценариях использования эта функция является последней, вызываемой отсоединенным потоком.
Параметры
| cond | - | условная переменная для уведомления при завершении потока |
| lk | - | блокировка, связанная с условной переменной cond |
Возвращаемое значение
(нет)
Пример
Этот фрагмент кода иллюстрирует, как
notify_all_at_thread_exit
может быть использован для предотвращения доступа к данным, зависящим от thread-local переменных, в процессе их разрушения:
#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"); }
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| 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 |
Смотрите также
|
устанавливает результат в определённое значение, доставляя уведомление только при завершении потока
(публичная функция-член
std::promise<R>
)
|
|
|
выполняет функцию, гарантируя, что результат будет готов только после выхода текущего потока
(публичная функция-член
std::packaged_task<R(Args...)>
)
|