Namespaces
Variants

std::condition_variable:: notify_all

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
(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
void notify_all ( ) noexcept ;
(начиная с C++11)

Разблокирует все потоки, ожидающие в данный момент * this .

Примечания

Эффекты notify_one() / notify_all() и каждой из трёх атомарных частей wait() / wait_for() / wait_until() (разблокировка+ожидание, пробуждение и блокировка) происходят в едином полном порядке, который можно рассматривать как порядок модификации атомарной переменной: этот порядок специфичен для данной конкретной переменной условия. Это делает невозможной ситуацию, когда notify_one() может быть, например, задержан и разблокирует поток, который начал ожидание сразу после вызова notify_one() .

Уведомляющий поток не обязан удерживать блокировку на том же мьютексе, который удерживают ожидающие потоки. Это может быть пессимизацией, поскольку уведомленный поток немедленно заблокируется снова, ожидая освобождения блокировки уведомляющим потоком, хотя некоторые реализации распознают данный шаблон и не пытаются пробудить поток, уведомленный под блокировкой.

Пример

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
std::condition_variable cv;
std::mutex cv_m; // Этот мьютекс используется для трех целей:
                 // 1) для синхронизации доступа к i
                 // 2) для синхронизации доступа к std::cerr
                 // 3) для переменной условия cv
int i = 0;
void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cerr << "Ожидание... \n";
    cv.wait(lk, []{ return i == 1; });
    std::cerr << "...ожидание завершено. i == 1\n";
}
void signals()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        std::cerr << "Уведомление...\n";
    }
    cv.notify_all();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        i = 1;
        std::cerr << "Повторное уведомление...\n";
    }
    cv.notify_all();
}
int main()
{
    std::thread t1(waits), t2(waits), t3(waits), t4(signals);
    t1.join(); 
    t2.join(); 
    t3.join();
    t4.join();
}

Возможный вывод:

Ожидание...
Ожидание...
Ожидание...
Уведомление...
Повторное уведомление...
...ожидание завершено. i == 1
...ожидание завершено. i == 1
...ожидание завершено. i == 1

Смотрите также

уведомляет один ожидающий поток
(публичная функция-член)
Документация C для cnd_broadcast