• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

c++11多线程编程之std::async的介绍与实例

c++ 搞代码 4年前 (2022-01-06) 22次浏览 已收录 0个评论

这篇文章主要给大家介绍了关于c++11多线程编程之std::async的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

本节讨论下在C++11中怎样使用std::async来执行异步task。

C++11中引入了std::async

什么是std::async

std::async()是一个接受回调(函数或函数对象)作为参数的函数模板,并有可能异步执行它们.

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

std::async返回一个 std::future,它存储由 std::async()执行的函数对象返回的值。

函数期望的参数可以作为函数指针参数后面的参数传递给std::async()。

std::async中的第一个参数是启动策略,它控制std::async的异步行为,我们可以用三种不同的启动策略来创建std::async

・std::launch::async

保证异步行为,即传递函数将在单独的线程中执行

・std::launch::deferred

当其他线程调用get()来访问共享状态时,将调用非异步行为

・std::launch::async | std::launch::deferred

默认行为。有了这个启动策略,它可以异步运行或不运行,这取决于系统的负载,但我们无法控制它。

如果我们不指定一个启动策略,其行为将类似于std::launch::async | std::launch::deferred

本节我们将使用std::launch::async启动策略

我们可以在std::async传递任何回调,如:

・函数指针

・函数对象

・lambda表达式

std::async的需求

假设我们必须从数据库和文件系统里里获取一些数据(字符串),然后需要合并字符串并打印。

在单线程中,我们这样做:

 #include  #include  #include  #include  using namespace std::chrono; std::string fetchDataFromDB(std::string recvData) { //确保函数要5秒才能执行完成 std::this_thread::sleep_for(seconds(5)); //处理创建数据库连接、获取数据等事情 return "DB_" + recvData; } std::string fetchDataFromFile(std::string recvData) { //确保函数要5秒才能执行完成 std::this_thread::sleep_for(seconds(5)); //处理获取文件数据 return "File_" + recvData; } int main() { //获取开始时间 system_clock::time_point start = system_clock::now(); //从数据库获取数据 std::string dbData = fetchDataFromDB("Data"); //从文件获取数据 std::string fileData = fetchDataFromFile("Data"); //获取结束时间 auto end = system_clock::now(); auto diff = duration_cast(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; }

输出:

Total Time Taken  = 10 Seconds
Data = DB_Data :: File_Data

由于函数  fetchDataFromDB() 和  fetchDataFromFile()各自在单独的线程中运行5秒,所以,总共耗时10秒。

既然从数据库和文件系统中获取数据是独立的并且都要耗时,那我们可以并行地运行他们。

一种方式是创建一个新的线程传递一个promise作为线程函数的参数,并在调用线程中从关联的std::future对象获取数据

另一种方式就是使用std::async

使用函数指针调用std::async作为回调

修改上面的代码,并使用std::async异步调用fetchDataFromDB()

 std::futureresultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data"); std::string dbData = resultDromDB.get()

std::async()做如下的事情

・自动创建一个线程(或从内部线程池中挑选)和一个promise对象。

・然后将std::promise对象传递给线程函数,并返回相关的std::future对象

・当我们传递参数的函数退出时,它的值将被设置在这个promise对象中,所以最终的返回值将在std::future对象中可用

现在改变上面的例子,使用std::async异步地从数据库中获取数据

 #include  #include  #include  #include  #include  using namespace std::chrono; std::string fetchDataFromDB(std::string recvData) { //确保函数要5秒才能执行完成 std::this_thread::sleep_for(seconds(5)); //处理创建数据库连接、获取数据等事情 return "DB_" + recvData; } std::string fetchDataFromFile(std::string recvData) { //确保函数要5秒才能执行完成 std::this_thread::sleep_for(seconds(5)); //处理获取文件数据 return "File_" + recvData; } int main() { //获取开始时间 system_clock::time_point start = system_clock::now(); std::future resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data"); //从文件获取数据 std::string fileData = fetchDataFromFile("Data"); //从DB获取数据 //<div style="color:transparent">来源gaodai^.ma#com搞#代!码网</div>数据在future对象中可获取之前,将一直阻塞 std::string dbData = resultFromDB.get(); //获取结束时间 auto end = system_clock::now(); auto diff = duration_cast(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; }

输出:

Total Time taken= 5Seconds
Data = DB_Data :: File_Data

只使用了5秒

用Function对象作为回调调用std::async

 /* * Function Object */ struct DataFetcher { std::string operator ()(std::string recvdData) { //确保函数要5秒才能执行完成 std::this_thread::sleep_for(seconds(5)); //处理获取文件数据 return "File_" + recvdData; } }; //用函数对象调用std::async std::future fileResult = std::async(DataFetcher(), "Data"); 

用lambda函数作为回调调用std::async

 std::future resultFromDB = std::async([](std::string recvdData) { std::this_thread::sleep_for(seconds(5)); //处理创建数据库连接、获取数据等事情 return "DB_" + recvdData; }, "Data"); 

总结

以上就是c++11多线程编程之std::async的介绍与实例的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:c++11多线程编程之std::async的介绍与实例

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址