C++11多線程異步操作std::future

本博客參考自https://thispointer.com/c11-tutorial/

C++多線程的在某些場景需要實現異步操作,由std::futer 和std::asych, std::packaged_task, std::promise搭配使用。

目錄

1.std::future

2.std::promise

3.std::asych

4.std::packaged_task


1.std::future

std::future是一個類模板,它的模板類可訪問“未來”的值,從而實現異步訪問。

創建語法:

與std::futer 和std::asych, std::packaged_task, std::promise搭配使用對應的創建語法如下

std::future<int> futureObj = promiseObj.get_future();
std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
std::future<std::string> result = task.get_future();

調用語法:

獲取future結果有三種方式:get、wait、wait_for,其中get等待異步操作結束並返回結果,wait只是等待異步操作完成,沒有返回值,wait_for是超時等待返回結果(參考自https://blog.csdn.net/daaikuaichuan/article/details/81173303

std::cout<<futureObj.get()<<std::endl; //在get到值之前程序會一直等待

 

2.std::promise

創建語法:

std::promise<int> promiseObj;

調用語法:

promObj->set_value(35);

完整代碼:

#include <iostream>
#include <thread>
#include <future>
 
void initiazer(std::promise<int> * promObj)
{
    std::cout<<"Inside Thread"<<std::endl;
    promObj->set_value(35);
}
 
int main()
{
    std::promise<int> promiseObj;
    std::future<int> futureObj = promiseObj.get_future();
    std::thread th(initiazer, &promiseObj);
    std::cout<<futureObj.get()<<std::endl;
    th.join();
    return 0;
}

3.std::asych

創建語法:

std::asych直接在創建時就與future變量關聯,並且創建對應的線程。與普通的多線程不同的是它可以通過future得到該線程函數的結果。

std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");

 

完整代碼:

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
 
using namespace std::chrono;
 
std::string fetchDataFromDB(std::string recvdData)
{
	// Make sure that function takes 5 seconds to complete
	std::this_thread::sleep_for(seconds(5));
 
	//Do stuff like creating DB Connection and fetching Data
	return "DB_" + recvdData;
}
 
std::string fetchDataFromFile(std::string recvdData)
{
	// Make sure that function takes 5 seconds to complete
	std::this_thread::sleep_for(seconds(5));
 
	//Do stuff like fetching Data File
	return "File_" + recvdData;
}
 
int main()
{
	// Get Start Time
	system_clock::time_point start = system_clock::now();
 
	std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
 
	//Fetch Data from File
	std::string fileData = fetchDataFromFile("Data");
 
	//Fetch Data from DB
	// Will block till data is available in future<std::string> object.
	std::string dbData = resultFromDB.get();
 
	// Get End Time
	auto end = system_clock::now();
 
	auto diff = duration_cast < std::chrono::seconds > (end - start).count();
	std::cout << "Total Time Taken = " << diff << " Seconds" << std::endl;
 
	//Combine The Data
	std::string data = dbData + " :: " + fileData;
 
	//Printing the combined Data
	std::cout << "Data = " << data << std::endl;
 
	return 0;
}

4.std::packaged_task

創建語法:

輸入模板是函數原型std::packaged_task<std::string (std::string)> task(getDataFromDB);初始化輸入的是函數getDataFromDB

std::packaged_task<std::string (std::string)> task(getDataFromDB);

調用語法:

這時packaged_task對象就相當於普通的回調函數,傳入thread對象實現多線程,與普通的多線程不同的是它可以通過future得到該線程函數的結果。

	// Fetch the associated future<> from packaged_task<>
	std::future<std::string> result = task.get_future();
 
	// Pass the packaged_task to thread to run asynchronously
	std::thread th(std::move(task), "Arg");

完整代碼:

#include <iostream>
#include <thread>
#include <future>
#include <string>
 
// Fetch some data from DB
std::string getDataFromDB( std::string token)
{
	// Do some stuff to fetch the data
	std::string data = "Data fetched from DB by Filter :: " + token;
	return data;
}
 
int main()
{
 
	// Create a packaged_task<> that encapsulated the callback i.e. a function
	std::packaged_task<std::string (std::string)> task(getDataFromDB);
 
	// Fetch the associated future<> from packaged_task<>
	std::future<std::string> result = task.get_future();
 
	// Pass the packaged_task to thread to run asynchronously
	std::thread th(std::move(task), "Arg");
 
	// Join the thread. Its blocking and returns when thread is finished.
	th.join();
 
	// Fetch the result of packaged_task<> i.e. value returned by getDataFromDB()
	std::string data =  result.get();
 
	std::cout <<  data << std::endl;
 
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章