天天看點

C++11多線程異步操作std::future1.std::future2.std::promise3.std::asych4.std::packaged_task

本部落格參考自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;
}
           
C++11多線程異步操作std::future1.std::future2.std::promise3.std::asych4.std::packaged_task

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;
}
           
C++11多線程異步操作std::future1.std::future2.std::promise3.std::asych4.std::packaged_task

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;
}
           
C++11多線程異步操作std::future1.std::future2.std::promise3.std::asych4.std::packaged_task