Espacios de nombres
Variantes
Acciones

std::stop_callback

De cppreference.com
< cpp‎ | thread
 
 
Biblioteca de apoyo de concurrencia
Hilos
(C++11)
(C++20)
Espacio de nombres this_thread
(C++11)
(C++11)
(C++11)
Cancelación cooperativa
(C++20)
stop_callback
(C++20)
Exclusión mutua
(C++11)
Gestión genérica de bloqueo
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Variables de condición
(C++11)
Semáforos
Pestillos y barreras
(C++20)
(C++20)
Futuros
(C++11)
(C++11)
(C++11)
(C++11)
Recuperación segura
(C++26)
Punteros de riesgo
Tipos atómicos
(C++11)
(C++20)
Inicialización de tipos atómicos
(C++11)(en desuso en C++20)
(C++11)(en desuso en C++20)
Orden de memoria
Funciones independientes para operaciones atómicas
Funciones independientes para indicadores atómicos
 
 
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) [editar]
Destruye el objeto stop_callback
(función miembro pública) [editar]
operator=
[eliminada]
stop_callback no es asignable
(función miembro pública) [editar]

[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