C++ Concurrency Guide std::async

First, let's look at the prototype of the std::async function:

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

It can be seen that async has three parameters, of which the first parameter is used to set the data interaction mode, the second parameter is a callable object (functor, lambda expression, class member function, ordinary function...), and the third The first parameter is the function parameter of the second parameter.

Whether the data interaction method is synchronous or asynchronous is determined by the first parameter:

  1. The callable object passed by std::launch::async is executed asynchronously;
  2. The callable object passed by std::launch::deferred is executed synchronously;
  3. std::launch::async | std::launch::deferred can be asynchronous or synchronous, depending on the operating system, we have no control;
  4. If we do not specify a strategy, it is equivalent to (3).

For the execution result, we can use get, wait, wait_for, wait_until to wait for the execution to end, the difference is that get can obtain the execution result. If the asynchronous execution strategy is selected, when the get is called, if the asynchronous execution does not end, get will block the current calling thread until the asynchronous execution ends and the result is obtained. If the asynchronous execution has ended, it does not wait to obtain the execution result; if the synchronous execution strategy is selected, only When the get function is called, the synchronous call is actually executed, which is also known as the function call is delayed.

The status of the returned result std::future:

  1. deffered: the asynchronous operation has not yet started;
  2. ready: the asynchronous operation has been completed;
  3. timeout: Asynchronous operation timeout.

Example 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;
}

Example 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;
}

Guess you like

Origin blog.csdn.net/qq_24649627/article/details/114837960