怎么在C++11中使用std::async方法
本篇文章给大家分享的是有关怎么在C++11中使用std::async方法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
std::async有两个版本:
1.无需显示指定启动策略,自动选择,因此启动策略是不确定的,可能是std::launch::async,也可能是std::launch::deferred,或者是两者的任意组合,取决于它们的系统和特定库实现。
2.允许调用者选择特定的启动策略。
std::async的启动策略类型是个枚举类enum class launch,包括:
1. std::launch::async:异步,启动一个新的线程调用Fn,该函数由新线程异步调用,并且将其返回值与共享状态的访问点同步。
2. std::launch::deferred:延迟,在访问共享状态时该函数才被调用。对Fn的调用将推迟到返回的std::future的共享状态被访问时(使用std::future的wait或get函数)。
参数Fn:可以为函数指针、成员指针、任何类型的可移动构造的函数对象(即类定义了operator()的对象)。Fn的返回值或异常存储在共享状态中以供异步的std::future对象检索。
参数Args:传递给Fn调用的参数,它们的类型应是可移动构造的。
返回值:当Fn执行结束时,共享状态的std::future对象准备就绪。std::future的成员函数get检索的值是Fn返回的值。当启动策略采用std::launch::async时,即使从不访问其共享状态,返回的std::future也会链接到被创建线程的末尾。在这种情况下,std::future的析构函数与Fn的返回同步。
std::future介绍参考:https://www.jb51.net/article/179229.htm
详细用法见下面的测试代码,下面是从其他文章中copy的测试代码,部分作了调整,详细内容介绍可以参考对应的reference:
#include"future.hpp" #include<iostream> #include<future> #include<chrono> #include<utility> #include<thread> #include<functional> #include<memory> #include<exception> #include<numeric> #include<vector> #include<cmath> #include<string> #include<mutex> namespacefuture_{ /////////////////////////////////////////////////////////// //reference:http://www.cplusplus.com/reference/future/async/ inttest_async_1() { autois_prime=[](intx){ std::cout<<"Calculating.Please,wait...\n"; for(inti=2;i<x;++i)if(x%i==0)returnfalse; returntrue; }; //callis_prime(313222313)asynchronously: std::future<bool>fut=std::async(is_prime,313222313); std::cout<<"Checkingwhether313222313isprime.\n"; //... boolret=fut.get();//waitsforis_primetoreturn if(ret)std::cout<<"Itisprime!\n"; elsestd::cout<<"Itisnotprime.\n"; return0; } /////////////////////////////////////////////////////////// //reference:http://www.cplusplus.com/reference/future/launch/ inttest_async_2() { autoprint_ten=[](charc,intms){ for(inti=0;i<10;++i){ std::this_thread::sleep_for(std::chrono::milliseconds(ms)); std::cout<<c; } }; std::cout<<"withlaunch::async:\n"; std::future<void>foo=std::async(std::launch::async,print_ten,'*',100); std::future<void>bar=std::async(std::launch::async,print_ten,'@',200); //async"get"(waitforfooandbartobeready): foo.get();//注:注释掉此句,也会输出'*' bar.get(); std::cout<<"\n\n"; std::cout<<"withlaunch::deferred:\n"; foo=std::async(std::launch::deferred,print_ten,'*',100); bar=std::async(std::launch::deferred,print_ten,'@',200); //deferred"get"(performtheactualcalls): foo.get();//注:注释掉此句,则不会输出'**********' bar.get(); std::cout<<'\n'; return0; } /////////////////////////////////////////////////////////// //reference:https://en.cppreference.com/w/cpp/thread/async std::mutexm; structX{ voidfoo(inti,conststd::string&str){ std::lock_guard<std::mutex>lk(m); std::cout<<str<<''<<i<<'\n'; } voidbar(conststd::string&str){ std::lock_guard<std::mutex>lk(m); std::cout<<str<<'\n'; } intoperator()(inti){ std::lock_guard<std::mutex>lk(m); std::cout<<i<<'\n'; returni+10; } }; template<typenameRandomIt> intparallel_sum(RandomItbeg,RandomItend) { autolen=end-beg; if(len<1000) returnstd::accumulate(beg,end,0); RandomItmid=beg+len/2; autohandle=std::async(std::launch::async,parallel_sum<RandomIt>,mid,end); intsum=parallel_sum(beg,mid); returnsum+handle.get(); } inttest_async_3() { std::vector<int>v(10000,1); std::cout<<"Thesumis"<<parallel_sum(v.begin(),v.end())<<'\n'; Xx; //Calls(&x)->foo(42,"Hello")withdefaultpolicy: //mayprint"Hello42"concurrentlyordeferexecution autoa1=std::async(&X::foo,&x,42,"Hello"); //Callsx.bar("world!")withdeferredpolicy //prints"world!"whena2.get()ora2.wait()iscalled autoa2=std::async(std::launch::deferred,&X::bar,x,"world!"); //CallsX()(43);withasyncpolicy //prints"43"concurrently autoa3=std::async(std::launch::async,X(),43); a2.wait();//prints"world!" std::cout<<a3.get()<<'\n';//prints"53" return0; }//ifa1isnotdoneatthispoint,destructorofa1prints"Hello42"here /////////////////////////////////////////////////////////// //reference:https://thispointer.com/c11-multithreading-part-9-stdasync-tutorial-example/ inttest_async_4() { usingnamespacestd::chrono; autofetchDataFromDB=[](std::stringrecvdData){ //Makesurethatfunctiontakes5secondstocomplete std::this_thread::sleep_for(seconds(5)); //DostufflikecreatingDBConnectionandfetchingData return"DB_"+recvdData; }; autofetchDataFromFile=[](std::stringrecvdData){ //Makesurethatfunctiontakes5secondstocomplete std::this_thread::sleep_for(seconds(5)); //DostufflikefetchingDataFile return"File_"+recvdData; }; //GetStartTime system_clock::time_pointstart=system_clock::now(); std::future<std::string>resultFromDB=std::async(std::launch::async,fetchDataFromDB,"Data"); //FetchDatafromFile std::stringfileData=fetchDataFromFile("Data"); //FetchDatafromDB //Willblocktilldataisavailableinfuture<std::string>object. std::stringdbData=resultFromDB.get(); //GetEndTime autoend=system_clock::now(); autodiff=duration_cast<std::chrono::seconds>(end-start).count(); std::cout<<"TotalTimeTaken="<<diff<<"Seconds"<<std::endl; //CombineTheData std::stringdata=dbData+"::"+fileData; //PrintingthecombinedData std::cout<<"Data="<<data<<std::endl; return0; } }//namespacefuture_
以上就是怎么在C++11中使用std::async方法,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注恰卡编程网行业资讯频道。