编程|基于future和promise模板,实现三种异步收发数据的方法

文章图片

文章图片

文章图片

文章图片

文章图片

文章图片
std::future和std::promise两者结合可以实现异步的功能场景 , 本文将介绍的异步收发数据模板类是在实践中结合std::future和std::promise而摸索出来的 。
工作过程中 , 我们可能会经常遇到这样的场景 , 需要从线程中获取运行的结果 。 现在我们有两种方式可以实现这样的效果 。
- 第一种方式 , 属于通用用法 , 通过使用指针在线程间共享数据 。 传递指针给新建的线程 , 主线程使用条件变量等待被唤醒;当线程设置完成数据到传递过来的指针之后 , 发送条件变量信号 , 主线程被唤醒之后 , 从指针中提取数据 。 这种方式采用条件变量、锁、指针结合才实现了异步功能 , 比较复杂 。
- 第二种方式 , 采用std::future和std::promise对象 , 也就是本文接下来要详细说明的一种异步实现方式 。
- std::future是一个类模板 , 内部存储一个将来用于分配的值 , 它提供了get()成员函数来访问该值的机制 。 如果关联值可用之前 , 调用了get函数 , 那么get函数将阻塞直到关联值不可用 。
- std::promise也是一个类模板 , 它用来设置上面的关联值 , 每一个stb::promise和一个std::future对象关联 , 一旦stb::promise设置值之后 , std::future对象的get()函数就会获取到值 , 然后返回 。 std::promise与它关联的std::future共享数据 。
2、定义std::promise对象 , 从该对象获取关联的std::future对象 , 启动线程并且传入std::promise对象的指针 , 调用std::future对象的get()函数阻塞等待 , 如果返回 , 那么打印输出返回的字符串信息 。
3、运行程序 , 输出的信息如下所示 , 从这里可以看出 , std::promise在线程中设置值之后 , std::future对象的get()函数成功获取并返回 。
二、通知线程退出基于std::promise和std::future的机制 , 我们可以利用std::promise的set_value来通知运行的线程退出 。 具体如何做呢 , 我们接下来给出例子进行说明 。
1、实现线程的执行函数 , 入参为与std::promise关联的std::future对象 , 执行函数内部调用std::future的wait_for循环超时等待 , 如果std::future的wait_for在超时时间内没有收到std::promise调用set_value发送的信号 , 那么继续循环等待 , 如果在超时时间内收到std::promise调用set_value发送的信号 , 那么退出循环 , 同时线程页退出了 。
【编程|基于future和promise模板,实现三种异步收发数据的方法】
2、创建std::promise对象 , 从std::promise对象提取关联的future对象 , 启动线程 , 并且将上面的future对象传递给线程 , 主线程休眠一段时间之后 , 调用std::promise对象的set_value函数来发送信号 , 通知线程退出 。
3、从输出的结果信息看 , 线程一直在运行 , 当收到std::promise对象发送信号的信号之后就退出 。
三、异步收发数据经过上面两个例子的讲解 , 相信大家对std::future和std::promise已经有了一个大概的了解 。 下面就给出异步收发数据的模板类 。
1、类模板JAsyncSender实现两个函数 , 一个是Send用于发送数据 , 它可以在线程中执行 , 另一个是Wait等待接收数据 , 如果第三个参数没有输入 , 那么默认一直等待 , 否则在指定时间内 , 没有收到信息 , 那么返回失败 。
2、接下来说明类模板JAsyncSender的使用方法
定义成员变量m_AsyncSendInt , 它由主线程和子线程共享 。 JAsyncSender的type为整形 , 也可以定义为字符串 , 甚至是自定义对象 , 根据具体需求场景具体定
通过lambda方式创建线程 , 当然你也可以使用其他方式 , 线程内部先休眠一段时间 , 然后发送数据 。
从运行结果看 , 基于future和promise实现的异步收发数据模板类的功能是正常的 。
四、总结std::promise与std::future的结合使用 , 可以更加容易处理异步消息事件 , 另外C++11标准中提供的 std::asych和std::packaged_task也是结合std::future来处理异步的事件流程 。 std::promise与std::future虽然功能强大 , 但是std::promise与std::future是一一对应的 , 目前没有办法处理一对多的问题 , 比如一个std::promise对应多个std::future 。 std::promise如果设置过一次 , 再次设置会报错 , 如果需要重新使用 , 需要再创建std::promise对象 。
推荐阅读
- 量子门|利用超导量子比特实现基于非绝热几何相的量子门
- 细胞|Sci Adv:重编程干细胞可有效治疗乳腺癌细胞向脑部转移
- 编程|又双叒叕出新动作啦!国科大推出可编程硅基光量子计算芯片
- 细胞|金刚狼战士:美军研发细胞“重新编程”技术,是自愈速度的5倍
- rnai|新药速递:首个基于RNAi疗法的新药ARC-520结果出炉!
- 极客|赋能4-16岁全阶段课程 极客晨星加码中国优质编程教育
- 2020WNEVC创新技术解读 | 基于昇腾AI的自动驾驶云服务技术
- 最新消息|约翰·传奇和娜塔莉·波特曼投资的MycoWorks可制造基于真菌的生物材料
- 乐睿童|没有人天生喜欢编程,兴趣也需要培养!
- Python 俄罗斯方块, 基于pyqt5实现俄罗斯方块 --pyqt5 进阶
