std::condition_variable_any:: notify_one
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
| Notification | ||||
|
condition_variable_any::notify_one
|
||||
| Waiting | ||||
|
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_any 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
Смотрите также
|
уведомляет все ожидающие потоки
(публичная функция-член) |
|
|
C documentation
для
cnd_signal
|
|