Guía de concurrencia de C ++ std :: async

Primero, veamos el prototipo de la función std :: async:

template<class Fn, class... Args>
future<typename result_of<Fn(Args...)>::type> async(launch policy, Fn&& fn, Args&&...args);

Se puede ver que async tiene tres parámetros, de los cuales el primer parámetro se usa para establecer el modo de interacción de datos, el segundo parámetro es un objeto invocable (functor, expresión lambda, función miembro de clase, función ordinaria ...) y el tercero El primer parámetro es el parámetro de función del segundo parámetro.

El primer parámetro determina si el método de interacción de datos es síncrono o asíncrono:

  1. El objeto invocable pasado por std :: launch :: async se ejecuta de forma asincrónica;
  2. El objeto invocable pasado por std :: launch :: deferred se ejecuta sincrónicamente;
  3. std :: launch :: async | std :: launch :: deferred puede ser asincrónico o síncrono, dependiendo del sistema operativo, no tenemos control;
  4. Si no especificamos una estrategia, es equivalente a (3).

Para el resultado de la ejecución, podemos usar get, wait, wait_for, wait_until para esperar a que finalice la ejecución, la diferencia es que get puede obtener el resultado de la ejecución. Si se selecciona la estrategia de ejecución asincrónica, cuando se llama a get, si la ejecución asincrónica no finaliza, get bloqueará el hilo de llamada actual hasta que finalice la ejecución asincrónica y se obtenga el resultado. Si la ejecución asincrónica ha finalizado, no lo hace. esperar para obtener el resultado de la ejecución; si se selecciona la estrategia de ejecución síncrona, solo cuando se llama a la función get, la llamada síncrona se ejecuta realmente, lo que también se conoce como la llamada a la función se retrasa.

El estado del resultado devuelto std :: future:

  1. diferido: la operación asíncrona aún no ha comenzado;
  2. listo: la operación asíncrona se ha completado;
  3. timeout: tiempo de espera de la operación asincrónica.

Ejemplo 1

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
 
using namespace std::chrono;
 
std::string fetchDataFromDB(std::string recvData) {
    
    
	std::cout << "fetchDataFromDB start " << std::this_thread::get_id() << std::endl;
	std::this_thread::sleep_for(seconds(5));
	return "DB_" + recvData;
}
 
std::string fetchDataFromFile(std::string recvData) {
    
    
	std::cout << "fetchDataFromFile start " << std::this_thread::get_id() << std::endl;
	std::this_thread::sleep_for(seconds(3));
	return "File_" + recvData;
}
 
int main() {
    
    
 
	std::cout << "main start" << std::this_thread::get_id() << std::endl;
 
	//获取开始时间
	system_clock::time_point start = system_clock::now();
 
	std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
 
	//从文件获取数据
	std::future<std::string> fileData = std::async(std::launch::deferred, fetchDataFromFile, "Data");
 
	//知道调用get函数fetchDataFromFile才开始执行
	std::string FileData = fileData.get();
	//如果fetchDataFromDB()执行没有完成,get会一直阻塞当前线程
	std::string dbData = resultFromDB.get();
	
	//获取结束时间
	auto end = system_clock::now();
 
	auto diff = duration_cast<std::chrono::seconds>(end - start).count();
	std::cout << "Total Time taken = " << diff << " Seconds. " << std::endl;
 
	//组装数据
	std::string data = dbData + " :: " + FileData;
 
	//输出组装的数据
	std::cout << "Data = " << data << std::endl;
 
	return 0;
}

Ejemplo 2

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
  
using namespace std::chrono;
  
std::string fetchDataFromDB(std::string recvData) {
    
    
  
    std::cout << "fetchDataFromDB start " << std::this_thread::get_id() << std::endl;
    std::this_thread::sleep_for(seconds(5));
    return "DB_" + recvData;
}
  
  
int main() {
    
    
  
    std::cout << "main start" << std::this_thread::get_id() << std::endl;
  
    //获取开始时间
    system_clock::time_point start = system_clock::now();
  
    std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
  
    std::future_status status;
    std::string dbData;
    do
    {
    
    
        status = resultFromDB.wait_for(std::chrono::seconds(1));
  
        switch (status)
        {
    
    
            case std::future_status::ready:
                std::cout << "Ready..." << std::endl;
                //获取结果
                dbData = resultFromDB.get();
                std::cout << dbData << std::endl;
                break;
            case std::future_status::timeout:
                std::cout << "timeout..." << std::endl;
                break;
            case std::future_status::deferred:
                std::cout << "deferred..." << std::endl;
                break;
            default:
                break;
        }
  
    } while (status != std::future_status::ready);
  
     
    //获取结束时间
    auto end = system_clock::now();
  
    auto diff = duration_cast<std::chrono::seconds>(end - start).count();
    std::cout << "Total Time taken = " << diff << " Seconds. " << std::endl;
  
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_24649627/article/details/114837960
Recomendado
Clasificación