Namespaces
Variants

std::condition_variable:: notify_one

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

Если какие-либо потоки ожидают на * this , вызов notify_one разблокирует один из ожидающих потоков.

Примечания

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

Уведомляющий поток не обязан удерживать блокировку на том же мьютексе, который удерживается ожидающим потоком(ами); фактически это является пессимизацией, поскольку уведомленный поток немедленно заблокируется снова, ожидая освобождения блокировки уведомляющим потоком. Однако некоторые реализации (в частности, многие реализации pthreads) распознают эту ситуацию и избегают сценария «поспеши и жди», передавая ожидающий поток из очереди переменной условия непосредственно в очередь мьютекса во время вызова уведомления, не пробуждая его.

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

Пример

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
std::condition_variable cv;
std::mutex cv_m;
int i = 0;
bool done = false;
void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cout << "Waiting... \n";
    cv.wait(lk, []{ return i == 1; });
    std::cout << "...finished waiting; i == " << i << '\n';
    done = true;
}
void signals()
{
    std::this_thread::sleep_for(200ms);
    std::cout << "Notifying falsely...\n";
    cv.notify_one(); // waiting thread is notified with i == 0.
                     // cv.wait wakes up, checks i, and goes back to waiting
    std::unique_lock<std::mutex> lk(cv_m);
    i = 1;
    while (!done) 
    {
        std::cout << "Notifying true change...\n";
        lk.unlock();
        cv.notify_one(); // waiting thread is notified with i == 1, cv.wait returns
        std::this_thread::sleep_for(300ms);
        lk.lock();
    }
}
int main()
{
    std::thread t1(waits), t2(signals);
    t1.join(); 
    t2.join();
}

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

Waiting... 
Notifying falsely...
Notifying true change...
...finished waiting; i == 1

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

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