C++11学习笔记-----获取异步操作执行结果

本文介绍了C++11中处理异步操作的方法,包括std::future、std::promise和std::packaged_task的使用。通过实例展示了如何在多线程环境中获取异步任务的结果,如并发执行std::find和std::for_each。std::promise提供了一种消息传递机制,用于存储值和异常;std::packaged_task可包装任何可调用对象,方便获取异步结果;std::async则能启动异步任务并返回future,支持立即执行或延迟执行。
摘要由CSDN通过智能技术生成

在多线程环境中,不管是传递lambda还是传递函数指针,再或者是传递函数对象给std::thread,都很难获取执行函数返回值。在以前,只能将结果以引用的形式作为线程函数参数的一部分以此保存返回值,但是仍然存在很大局限性,甚至不太美观。C++11引入的std::future可以有效解决这一问题。

std::future定义在头文件<future>中,提供了一种获取异步操作返回值的机制,不过通常与下列三个配合使用

  • std::promise
  • std::packaged_task
  • std::async

这三个操作各有不同,但是都有一个共同点就是都提供了get_future接口用于获得与之关联的future,使用者(主线程)可以通过返回的future获得异步操作结果。

std::promise

简单来说,promise是一种用于消息传递的机制,或者说是提供存储值和异常的设施。当创建线程时可以将promise引用传给线程函数,当在线程函数(异步操作)中计算得知了主线程想要的结果后通过promise::set_value*等接口设置值(如果出现异常也可以设置异常)。而主线程可以通过从promise获取的future获取结果

示例:利用std::future和std::promise实现并发std::find函数

和并发std::accumulate的实现类似,首先计算合适的线程数,将给定区间拆分成若干小区间,并行执行查找操作,当找到结果后,通过std::promise设置查找结果,而主线程则通过std::future获取结果

#include <future>
#include <thread>
#include <vector>
#include <algorithm>
#include <cassert>

namespace parallel
{
    template <class InputIt, class T>
    InputIt find(InputIt first, InputIt last, const T& value)
    {
        /* 
         * 计算合适的线程数
         * std::thread::hardware_concurrency()用于返回当前系统支持的并发数
         */
        auto count = std::distance(first, last);
        auto avaThreadNums = std::thread::hardware_concurrency();
        auto perThreadMinNums = 20;
        auto maxThreadNums = ((count + (perThreadMinNums - 1)) & (~(perThreadMinNums - 1))) / perThreadMinNums;
        auto threadNums = 
            avaThreadNums == 0 ? 
                maxThreadNums : 
                std::min(<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值