0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

async的两个坑

汽车电子技术 来源:程序喵大人 作者:程序喵 2023-02-21 14:01 次阅读

一般人可能都知道C++异步操作有async这个东西。但不知道大家是否注意过,其实它有两个坑:

  1. 它不一定真的会异步执行
  2. 它有可能会阻塞

下面是async具体的介绍:

async是比future,packaged_task,promise更高级的东西,它是基于任务的异步操作。

通过async可以直接创建异步的任务,返回的结果会保存在future中,不需要像packaged_task和promise那么麻烦。

关于线程操作可以优先使用async,看一段使用代码:

#include 
#include 
#include 
#include 


using namespace std;


int func(int in) { return in + 1; }


int main() {
    auto res = std::async(func, 5);
    // res.wait();
    cout << res.get() << endl;  // 阻塞直到函数返回
    return 0;
}

使用async异步执行函数是不是方便多啦。

async具体语法如下:

async(std::launch::async | std::launch::deferred, func, args...);

第一个参数是创建策略:

  • std::launch::async表示任务执行在另一线程
  • std::launch::deferred表示延迟执行任务,调用get或者wait时才会执行,不会创建线程,惰性执行在当前线程。

如果不明确指定创建策略,以上两个都不是async的默认策略,而是undefined,它是一个基于任务的程序设计,内部有一个调度器(线程池),会根据实际情况决定采用哪种策略。

若从 std::async 获得的 std::future 未被移动或绑定到引用,则在完整表达式结尾。

注意:std::future的析构函数将阻塞直至异步计算完成,实际上相当于同步操作:

std::async(std::launch::async, []{ f(); }); // 临时量的析构函数等待 f()
std::async(std::launch::async, []{ g(); }); // f() 完成前不开始

注意:关于async启动策略这里网上和各种书籍介绍的五花八门,这里会以cppreference为主。

有时候我们如果想真正执行异步操作可以对async进行封装,强制使用std::launch::async策略来调用async。

template <typename F, typename... Args>
inline auto ReallyAsync(F&& f, Args&&... params) {
    return std::async(std::launch::async, std::forward(f), std::forward(params)...);
}

参考资料

https://en.cppreference.com/w/cpp/thread/async

打完收工。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 操作
    +关注

    关注

    0

    文章

    43

    浏览量

    18847
  • C++
    C++
    +关注

    关注

    21

    文章

    2102

    浏览量

    73457
收藏 人收藏

    评论

    相关推荐

    PCB板返修时的两个关键工艺

    . 引言   对于成功返修SMT起帮助作用的两个最关键工艺,也是两个
    发表于 04-16 21:33 2061次阅读

    两个分机的对讲电话

    两个分机的对讲电话
    发表于 05-01 01:07 1179次阅读
    有<b class='flag-5'>两个</b>分机的对讲电话

    两个可变零点、两个固定极点的有源滤波器

    两个可变零点、两个固定极点的有源滤波器
    发表于 04-15 10:51 583次阅读
    有<b class='flag-5'>两个</b>可变零点、<b class='flag-5'>两个</b>固定极点的有源滤波器

    两个实用的串口调试助手

    电子发烧友网站提供《两个实用的串口调试助手.zip》资料免费下载
    发表于 07-22 15:22 8次下载

    合并两个排序的链表

    合并两个排序的链表一、题目要求 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 二、我的思路 1、比较两个链表的头结点大小,哪个小就将其作
    发表于 01-16 22:02 569次阅读

    如何测量两个光源的相对强度?

    Q: 是否可以使用仪表放大器测量两个光源之间的差异?A: 是的,用两个光敏电阻替换仪表放大器的主设定电阻就可
    的头像 发表于 02-03 12:45 5880次阅读
    如何测量<b class='flag-5'>两个</b>光源的相对强度?

    两个电机的电路开源

    电子发烧友网站提供《两个电机的电路开源.zip》资料免费下载
    发表于 08-03 11:20 1次下载
    <b class='flag-5'>两个</b>电机的电路开源

    async-backtrace使用步骤

    使用 #[async_backtrace::framed] 标注一异步函数可用于追踪,使用 taskdump_tree 以树的形式输出当前所有被追踪的任务状态
    的头像 发表于 11-02 09:38 494次阅读
    <b class='flag-5'>async</b>-backtrace使用步骤

    如何控制两个电机直流

    电子发烧友网站提供《如何控制两个电机直流.zip》资料免费下载
    发表于 11-21 14:35 0次下载
    如何控制<b class='flag-5'>两个</b>电机直流

    在trait中使用 `async fn`

    在 trait 中使用 async fn async 工作组很高兴地宣布 async fn 现在可以在 nightly 版本的 traits 中使用。在 playground 上有一
    的头像 发表于 11-23 15:40 752次阅读

    分享两个STM32应用中的实战案例

    今天在此分享两个STM32应用中的实战案例,权作提醒,以免重蹈覆辙。
    的头像 发表于 01-11 09:13 3593次阅读

    如何使用两个LED和Arduino

    电子发烧友网站提供《如何使用两个LED和Arduino.zip》资料免费下载
    发表于 01-30 11:28 1次下载
    如何使用<b class='flag-5'>两个</b>LED和Arduino

    两个LED和两个按钮的使用

    电子发烧友网站提供《两个LED和两个按钮的使用.zip》资料免费下载
    发表于 01-30 16:04 1次下载
    <b class='flag-5'>两个</b>LED和<b class='flag-5'>两个</b>按钮的使用

    如何判断两个链表是否相交,假设两个链表都没有环?

    首先,很多同学会存在一误区,认为两个链表相交应该这样的。
    的头像 发表于 08-08 17:08 954次阅读
    如何判断<b class='flag-5'>两个</b>链表是否相交,假设<b class='flag-5'>两个</b>链表都没有环?

    两个硬盘2系统开机切换

    切换两个硬盘上的系统是一种常见的行为,可以让用户在不同的操作系统之间进行切换,以满足不同的需求。在本文中,我们将详细介绍如何配置和使用两个硬盘上的系统进行切换。本文将分为以下几个部分进行讨论:硬件
    的头像 发表于 11-28 15:08 7209次阅读