std::promise
Definido en el archivo de encabezado <future>
|
||
template< class R > class promise; |
(1) | (desde C++11) |
template< class R > class promise<R&>; |
(2) | (desde C++11) |
template<> class promise<void>; |
(3) | (desde C++11) |
La plantilla de clase std::promise
(o promesa) proporciona un servicio para almacenar un valor o una excepción que luego se adquiere de forma asincrónica a través de un objeto std::future creado por el objeto promesa. Ten en cuenta que el objeto promesa está destinado a usarse solo una vez.
Cada objeto promesa está asociado con un estado compartido, que contiene algo de información del estado, y un resultado que puede no estar evaluado todavía, evaluado a un valor (posiblemente void), o evaluado a una excepción. Un objeto promesa puede hacer tres cosas con el estado compartido:
- dejarlo listo: el objeto promesa almacena el resultado o la excepción en el estado compartido. Marca el estado como listo y desbloquea cualquier hilo en espera de un objeto futuro (std::future) asociado con el estado compartido.
- liberarlo: el objeto promesa renuncia a su referencia al estado compartido. Si esta era la última referencia, el estado compartido se destruye. A menos que este sea un estado compartido creado por std::async que aún no está listo, esta operación no se bloquea.
- abandonarlo: el objeto promesa almacena la excepción de tipo std::future_error con el código de error std::future_errc::broken_promise, deja el estado compartido listo, y luego lo libera.
El objeto promesa es el "empuje" al final del canal de comunicaciones entre objetos promesa-futuro: la operación que almacena un valor en el estado compartido se sincroniza-con (como se define en std::memory_order) el retorno exitoso de cualquier función que está a la espera del estado compartido (tal como std::future::get). De lo contrario, el acceso concurrente al mismo estado compartido puede tener conflicto: por ejemplo, múltiples llamantes de std::shared_future::get deben o bien ser todos de solo lectura o proporcionar sincronización externa.
Contenido |
[editar] Funciones miembro
Construye un objeto promesa. (función miembro pública) | |
Destruye el objeto promesa. (función miembro pública) | |
Asigna el estado compartido. (función miembro pública) | |
Intercambia dos objetos promesa. (función miembro pública) | |
Obtener el resultado | |
Devuielve un objeto future asociado con el resultado prometido. (función miembro pública) | |
Establecer el resultado | |
Establece el resultado a un valor específico. (función miembro pública) | |
Establece el resultado a un valor específico mientras notifica solamente cuando el hilo termina. (función miembro pública) | |
Establece el resultado para indicar una excepción. (función miembro pública) | |
Establece el resultado para indicar una excepción mientras notifica solamente cuando el hilo termina. (función miembro pública) |
[editar] Funciones no miembro
(C++11) |
Especializa el algoritmo std::swap. (plantilla de función) |
[editar] Clases auxiliares
Especializa el rasgo de tipo std::uses_allocator (especialización de plantilla de clase) |
[editar] Ejemplo
Este ejemplo muestra cómo los objetos promise<int>
pueden usarse como señales entre hilos.
#include <vector> #include <thread> #include <future> #include <numeric> #include <iostream> #include <chrono> void accumulate(std::vector<int>::iterator first, std::vector<int>::iterator last, std::promise<int> accumulate_promise) { int sum = std::accumulate(first, last, 0); accumulate_promise.set_value(sum); // Notificar a objeto future } void do_work(std::promise<void> barrier) { std::this_thread::sleep_for(std::chrono::seconds(1)); barrier.set_value(); } int main() { // Demuestra el uso de promise<int> para transmitir // un resultado entre hilos. std::vector<int> numbers = { 1, 2, 3, 4, 5, 6 }; std::promise<int> accumulate_promise; std::future<int> accumulate_future = accumulate_promise.get_future(); std::thread work_thread(accumulate, numbers.begin(), numbers.end(), std::move(accumulate_promise)); // future::get() esperará hasta que el objeto future // tenga un resultado válido y lo recuperará // No se necesita llamar a wait() antes que a get() //accumulate_future.wait(); // espera el resultado std::cout << "result=" << accumulate_future.get() << '\n'; work_thread.join(); // esperar a que termine el hilo // Demuestra el uso de promise<void> // para señalar estado entre hilos std::promise<void> barrier; std::future<void> barrier_future = barrier.get_future(); std::thread new_work_thread(do_work, std::move(barrier)); barrier_future.wait(); new_work_thread.join(); }
Salida:
result=21