std::stop_callback
Definido en el archivo de encabezado <stop_token>
|
||
template< class Callback > class stop_callback; |
(desde C++20) | |
La plantilla de clase stop_callback
proporciona un tipo objeto RAII con una función de devolución de llamada para un objeto std::stop_token asociado, de modo que la función de devolución de llamada se invocará cuando al objeto std::stop_source asociado con el std::stop_token se le solicite que se detenga.
Las funciones de devolución de llamada registradas mediante el constructor de stop_callback
se invocan ya sea en el mismo hilo/subproceso que exitosamente invoque a request_stop() para un std::stop_source del std::stop_token asociado con el objeto stop_callback
; o si ya se ha solicitado una detención anteriormente al registro del constructor, entonces la devolución de llamada se invoca en el hilo/subproceso que construye al objeto stop_callback
.
Se puede crear más de un objeto stop_callback
para el mismo std::stop_token, a partir del mismo hilo/subproceso o de distintos hilos simultáneos. No se da una garantía del orden en el que se ejecutarán, pero se invocarán sincrónicamente, excepto para los objetos stop_callback
construidos después de que se ha solicitado la detención para el std::stop_token, como se describió previamente.
Si una invocación de una devolución de llamada egresa mediante una excepción, entoces se llama a std::terminate.
std::stop_callback
no es ni CopyConstructible, CopyAssignable, MoveConstructible, ni MoveAssignable.
El tipo del parámetro de plantilla Callback
debe ser tanto invocable
como destructible
. Cualquier valor de retorno se ignora.
Contenido |
[editar] Tipos miembro
Tipo | Definición |
callback_type
|
Callback
|
[editar] Funciones miembro
Construye un nuevo objeto stop_callback (función miembro pública) | |
Destruye el objeto stop_callback (función miembro pública) | |
operator= [eliminada] |
stop_callback no es asignable (función miembro pública) |
[editar] Guías de deducción
[editar] Ejemplo
#include <chrono> #include <condition_variable> #include <iostream> #include <mutex> #include <sstream> #include <thread> using namespace std::chrono_literals; // Uso de clase auxiliar para flujo atómico de std::cout class Writer { std::ostringstream buffer; public: ~Writer() { std::cout << buffer.str(); } Writer& operator<<(auto input) { buffer << input; return *this; } }; int main() { // Un hilo obrero // Esperará hasta que se solicite que se detenga. std::jthread worker([] (std::stop_token stoken) { Writer() << "id del hilo obrero: " << std::this_thread::get_id() << '\n'; std::mutex mutex; std::unique_lock lock(mutex); std::condition_variable_any().wait(lock, stoken, [&stoken] { return stoken.stop_requested(); }); }); // Registrar una devolución de llamada de detención en el hilo obrero. std::stop_callback callback(worker.get_stop_token(), [] { Writer() << "Devolución de llamada de detención ejecutada por el hilo: " << std::this_thread::get_id() << '\n'; }); // los objetos stop_callback objects pueden destruirse prematuramente // para prevenir su ejecución { std::stop_callback scoped_callback(worker.get_stop_token(), [] { // Esto no se ejecutará. Writer() << "Devolución de llamada de detención con ámbito ejecutada por el hilo: " << std::this_thread::get_id() << '\n'; }); } // Demostrar cuál hilo ejecuta a stop_callback cuándo. // Definir una función de detención auto stopper_func = [&worker] { if(worker.request_stop()) Writer() << "Solicitud de detención ejecutada por el hilo: " << std::this_thread::get_id() << '\n'; else Writer() << "Solicitud de detención no ejecutada por el hilo: " << std::this_thread::get_id() << '\n'; }; // Dejemos que múltiples hilos compitan por detener al hilo obrero std::jthread stopper1(stopper_func); std::jthread stopper2(stopper_func); stopper1.join(); stopper2.join(); // Después de que se ha solicitado una detención, // una nueva stop_callback se ejecuta inmediatemente. Writer() << "Hilo principal: " << std::this_thread::get_id() << '\n'; std::stop_callback callback_after_stop(worker.get_stop_token(), [] { Writer() << "Devolución de llamada de detención ejecutada por el hilo: " << std::this_thread::get_id() << '\n'; }); }
Posible salida:
id del hilo obrero: 140460265039616 Devolución de llamada de detención ejecutada por el hilo: 140460256646912 Solicitud de detención ejecutada por el hilo: 140460256646912 Solicitud de detención no ejecutada por el hilo: 140460248254208 Hilo principal: 140460265043776 Devolución de llamada de detención ejecutada por el hilo: 140460265043776