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

    浏览量

    18796
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72900
收藏 人收藏

    评论

    相关推荐

    multisim 如何叠加两个两个信号

    的)那么接下来就为了验证这个电路到底能不能滤除两个信号中的一信号,以及再放大这个信号。那么~~~~那么~~~~那么是不是就需要一混合了两个信号的信号(比如
    发表于 03-03 17:55

    两个VCC

    大哥,两个VCC,比如一5V,一9V的怎么画原理图加以区别呀???望指教
    发表于 08-11 11:30

    两个按钮如何分别进入两个不同的界面

    我想在一主VI上设置两个按钮,点击能够分别进入两个不同的子VI,按我图片上的框图程序,我是按相同程序编的两个按钮,但只能进入第一子VI,
    发表于 05-05 12:28

    两个keil合成一

    用keil写了两个程序,分别是屏幕显示汉字和按键控制led灯!!两个程序都是正确的,怎么才能合成一啊?
    发表于 05-20 17:59

    写了两个FPGA程序,是两个模块,如何将这两个模块连接到...

    写了两个FPGA程序,是两个模块,如何将这两个模块连接到一起进行编译仿真。应该如何操作。
    发表于 06-06 13:40

    两个电容的问题

    谁能帮我解释一下 这两个电容是什么意思
    发表于 09-21 18:28

    启动两个while问题

    请问两个不同的程序,程序1开始后也同时让程序2开始,两个都是while循环程序,改怎样设置呢?
    发表于 11-20 11:34

    labview实现两个按钮互斥,采用属性节点禁用的方法。但是...

    本帖最后由 老板很爹 于 2014-4-24 19:38 编辑 labview实现两个按钮互斥,采用属性节点禁用的方法。但是禁用之后以后都不能再用了怎么办?已解决。不过还是要手动关闭按钮,不知各位有没有比较好的办法?
    发表于 04-23 22:50

    ML之MLiR:输入两个向量,得出两个向量之间的相关度

    ML之MLiR:输入两个向量,得出两个向量之间的相关度
    发表于 12-24 11:54

    怎么把ad中一工程的两个不同的原理图生成两个pcb?

    ad中一工程的两个不同的原理图怎么生成两个pcb
    发表于 08-27 01:53

    两个代码

    你好,我想问一下,这是需要编写两个代码吗?
    发表于 12-12 18:20

    两个装置同时发光怎么实现

    两个装置都有灯,靠近两个装置的灯同时亮,离开两个同时灭,。只有两个靠近才可以亮,离开同时灭。通过什么可以实现。
    发表于 03-05 01:42

    Gowin WB Async Bridge IP用户指南

    Gowin WB Async Bridge IP用户指南主要内容包括功能描述、端口描述、配置调用等。主要用于帮助用户快速了解 Gowin WB Async Bridge IP 的产品特性、特点及使用方法。
    发表于 10-10 10:34

    async-backtrace使用步骤

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

    在trait中使用 `async fn`

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