Namespaces
Variants

std:: notify_all_at_thread_exit

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
notify_all_at_thread_exit
(C++11)
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
Определено в заголовочном файле <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...)> )