std::jthread::request_stop
bool request_stop() noexcept; | (начиная с C++20) |
Отправляет запрос на остановку внутреннему состоянию остановки, если запрос на остановку ещё не был отправлен.
Проверка выполняется атомарно. Если запрос на остановку был отправлен, состояние остановки атомарно обновляется во избежание состояний гонки, что гарантирует следующее:
-
stop_requested()иstop_possible()можно вызывать одновременно для другихstd::stop_tokenиstd::stop_source, связанных с тем же общим состоянием остановки. -
request_stop()можно одновременно вызывать из нескольких потоков для одного и того же объектаjthreadили других объектовstd::stop_source, связанных с тем же состоянием остановки, и только один вызов фактически отправит запрос на остановку.
Однако см. раздел «Примечания».
Параметры
(нет)
Возвращаемое значение
true, если этот вызов отправил запрос на остановку; в противном случае — false.
Постусловия
Для объекта std::stop_token, полученного с помощью get_stop_token(), или объекта std::stop_source, полученного с помощью get_stop_source(), stop_requested() имеет значение true.
Примечания
Если объект request_stop() отправляет запрос на остановку (то есть возвращает true), то все объекты std::stop_callbacks, зарегистрированные для того же связанного состояния остановки, будут вызваны синхронно в том же потоке, в котором отправлен request_stop(). Если вызов функции обратного вызова завершается исключением, вызывается std::terminate.
Если запрос на остановку уже был отправлен, эта функция возвращает false. Однако нет гарантии, что другой поток или объект std::stop_source, который только что (успешно) отправил запрос на остановку для того же состояния остановки, уже завершил вызов функции std::stop_callback.
Если объект request_stop() отправляет запрос на остановку (то есть возвращает true), то все условные переменные базового типа std::condition_variable_any, зарегистрированные для прерываемого ожидания объектов std::stop_token, связанных с внутренним состоянием остановки объекта jthread, будут разбужены.
Пример
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std::chrono_literals;
// Helper function to quickly show which thread printed what
void print(auto txt)
{
std::cout << std::this_thread::get_id() << ' ' << txt;
}
int main()
{
// A sleepy worker thread
std::jthread sleepy_worker(
[](std::stop_token stoken)
{
for (int i = 10; i; --i)
{
std::this_thread::sleep_for(300ms);
if (stoken.stop_requested())
{
print("Sleepy worker is requested to stop\n");
return;
}
print("Sleepy worker goes back to sleep\n");
}
});
// A waiting worker thread
// The condition variable will be awoken by the stop request.
std::jthread waiting_worker(
[](std::stop_token stoken)
{
std::mutex mutex;
std::unique_lock lock(mutex);
std::condition_variable_any().wait(lock, stoken, []{ return false; });
print("Waiting worker is requested to stop\n");
return;
});
// Sleep this thread to give threads time to spin
std::this_thread::sleep_for(400ms);
// std::jthread::request_stop() can be called explicitly:
print("Requesting stop of sleepy worker\n");
sleepy_worker.request_stop();
sleepy_worker.join();
print("Sleepy worker joined\n");
// Or automatically using RAII:
// waiting_worker's destructor will call request_stop()
// and join the thread automatically.
}
Возможный вывод:
140287602706176 Sleepy worker goes back to sleep 140287623300928 Requesting stop of sleepy worker 140287602706176 Sleepy worker is requested to stop 140287623300928 Sleepy worker joined 140287594313472 Waiting worker is requested to stop
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/thread/jthread/request_stop