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) |
void, usada para comunicar objetos entre hilos.void, usada para comunicar eventos sin estado.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::asyncque 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.
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) | |
Funciones no miembro
(C++11) |
Especializa el algoritmo std::swap. (plantilla de función) |
Clases auxiliares
| Especializa el rasgo de tipo std::uses_allocator (especialización de plantilla de clase) |
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