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.
Tipos miembro
| Tipo | Definición |
callback_type
|
Callback
|
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) |
Guías de deducción
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