C ++ 11 线程 promesa, futuro, asíncrono, packaged_task

1.Promise 和 futuro

Papel y la futura promesa es para pasar datos entre diferentes hilos. También se puede hacer usando el puntero para transferir datos, pero los punteros son muy peligrosos debido a la exclusión mutua no puede bloquear el acceso al puntero; puntero y método de transferencia de datos es fijo, si cambia el tipo de datos, también es necesario el cambio de la interfaz, más problemas ; apoyo promesa para las operaciones de genéricos proceso de programación más conveniente.

Supongamos que un hilo para un hilo 2 de datos, a continuación, utilizar la siguiente combinación:

Thread 1 inicializa un futuro del objeto objetivo y una promesa, la promesa para transferir el hilo 2, un compromiso correspondiente al hilo 1, el hilo 2; correspondiente a un futuro acepta una promesa para el valor futuro de la rosca 2 adquiere la transmisión
de rosca 2 adquiere prometen , es necesario transferir los datos relacionados con esta promesa, luego pase el futuro 1 puede obtener los datos.
Si desea obtener datos de hilo 1, el hilo 2 y datos no mostrados, la secuencia de rosca 1 hasta que los datos llegan a la rosca 2.

El hilo 1 se detecta siempre y cuando llegan los datos, manos a la obra, el estado del extremo de lata rosca 2 puede continuar funcionando.

// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
#include <thread>
#include <future>
#include <numeric>
#include <iostream>
#include <chrono>

// 计算一个vector数组的和,并设置一个promise,这是一个承诺,需要设置这个值
void accumulate(std::vector<int>::iterator first,
	std::vector<int>::iterator last,
	std::promise<int> accumulate_promise)
{
	int sum = std::accumulate(first, last, 0);
	std::cout << "set promise\n";
	accumulate_promise.set_value(sum);// Notify future
	std::this_thread::sleep_for(std::chrono::seconds(10));
}

void do_work(std::promise<void> barrier)
{
	std::this_thread::sleep_for(std::chrono::seconds(1));
	barrier.set_value();
	std::this_thread::sleep_for(std::chrono::seconds(10));
}

int main()
{
	// Demonstrate using promise<int> to transmit a result between threads.
	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));

	std::cout << "result=" << accumulate_future.get() << "\n";
	work_thread.join();

	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();
    return 0;
}

 

2.async

(Advanced Packaging futuro e hilo)

ejecuta una función asíncrona (potencialmente en un nuevo hilo) y devuelve un  std :: futuro  que contendrá el resultado

ejecución asíncrono una función (probablemente en el nuevo hilo) y vuelve a guardar los resultados de std :: futuro

// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
#include <thread>
#include <future>
#include <numeric>
#include <iostream>
#include <chrono>

bool is_prime(int x)
{
	for (int i = 2; i < x; i++) {
		if (x%i == 0)
			return false;
	}
	return true;
}

int main()
{
	// call function asynchronously;
	std::future<bool> fut = std::async(is_prime, 4444444443);

	// do something while waiting for function to set future.
	std::cout << "checking,please wait...";
	std::chrono::milliseconds span(100);
	while (fut.wait_for(span) == std::future_status::timeout)
	{
		std::cout << '.' << std::flush;
	}
	bool x = fut.get();
	std::cout << "\n4444444443 " << (x ? "is" : "is not") << " prime.\n";

    return 0;
}

El resultado:

Después de std :: asíncrono primero crear un is_prime ejecución del hilo (4444444443), la creación de empleo, retornos std :: asincrónicos un std :: futuro inmediato objetos.

 El hilo principal puede utilizar std :: :: futuro llegar llegar los resultados, si el proceso de la llamada, la tarea no se ha completado, el hilo principal está bloqueada hasta que se complete la tarea.

 El hilo principal también se puede utilizar std :: :: futuro wait_for esperar los resultados devueltos, wait_for puede establecer el tiempo de espera, si la tarea se ha completado dentro del período de tiempo de espera, los rendimientos std :: :: future_status estado preparado, y si la tarea dentro del tiempo de espera todavía , declaraciones de std :: future_status completos :: estado de tiempo de espera.

3.packaged_task

std :: papel packaged_task es proporcionar un mecanismo de sincronización de datos entre los diferentes hilos, una función que puede almacenar operación, y devuelve el valor pasado al futuro correspondiente, pero en el futuro puede ser otro hilo para acceso seguro este valor.

Código de ejemplo:

// threadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
#include <thread>
#include <future>
#include <numeric>
#include <iostream>
#include <chrono>

int countdown(int from, int to)
{
	for (int i = from; i != to; --i)
	{
		std::cout << i << '\n';
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	std::cout << "Lift off!\n";
	return from - to;
}

int main()
{
	std::packaged_task<int(int, int)> tsk(countdown);
	std::future<int> ret = tsk.get_future();
	std::thread th(std::move(tsk), 10, 0);
	// ...
	int value = ret.get();// wait for the task to finish and get result
	std::cout << "The countdown lasted for " << value << " seconds.\n";
	th.join();
    return 0;
}

El resultado:

Publicados 257 artículos originales · ganado elogios 22 · Vistas a 90000 +

Supongo que te gusta

Origin blog.csdn.net/qq_24127015/article/details/104819447
Recomendado
Clasificación