Spec-Zone.ru › C++

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() происходит после (как определено в std::memory_order) уничтожения всех объектов с временем жизни thread local, связанных с текущим потоком.

Аналогичный эффект можно достичь с помощью средств, предоставляемых std::promise или std::packaged_task.

Примечания

Вызов этой функции, если lock.mutex() не заблокирован текущим потоком, является неопределенным поведением.

Вызов этой функции, если lock.mutex() не совпадает с мьютексом, используемым всеми другими потоками, которые в настоящее время ожидают той же переменной состояния, является неопределенным поведением.

Предоставленный замок lk удерживается до выхода потока. После вызова этой функции, больше ни один поток не может получить тот же замок для ожидания cond. Если некоторые потоки ожидают этой переменной состояния, убедитесь, что ожидаемое условие выполняется при удержании замка на lk, и что этот замок не освобождается и не перезахватывается до вызова notify_all_at_thread_exit для предотвращения путаницы из-за ложных пробуждений в других потоках.

В типичных случаях использования эта функция является последним вызовом в отсоединённом потоке.

Параметры

cond - переменная состояния, которую необходимо уведомить при выходе потока
lk - замок, связанный с переменной состояния cond

Возвращаемое значение

(нет)

Пример

Этот фрагмент частичного кода демонстрирует, как notify_all_at_thread_exit может быть использован для предотвращения доступа к данным, которые зависят от thread locals, в то время как эти thread locals находятся в процессе уничтожения:

#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");
}

См. также

set_value_at_thread_exit
устанавливает результат в определённое значение, доставляя уведомление только при выходе потока
(публичный член-функция std::promise<R>)
make_ready_at_thread_exit
выполняет функцию, гарантируя, что результат готов только после выхода текущего потока
(публичный член-функция std::packaged_task<R(Args...)>)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/thread/notify_all_at_thread_exit

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API