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

Поведение не определено, если выполняется любое из следующих условий:

  • 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, чтобы избежать доступа к данным, зависящим от локальных для потока объектов, пока эти объекты уничтожаются:

#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++.

Отчёт об ошибке Применимо к Опубликованное поведение Правильное поведение
LWG 2140 C++11 вызов notify_all_at_thread_exit
синхронизирован с вызовами функций, ожидающих на cond
требование к синхронизации
обновлено

См. также

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/cpp/thread/notify_all_at_thread_exit

Spec-Zone.ru

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