基于C++模板,实现三种异步收发数据的方法

开发 前端
std::future和std::promise两者结合可以实现异步的功能场景,本文将介绍的异步收发数据模版类是在实践中结合std::future和std::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共享数据。

一、阻塞等待获取数据

1、实现线程执行函数,入参是一个std::promise指针,函数内调用std::promise指针设置值

 

基于C++模板,实现三种异步收发数据的方法

2、定义std::promise对象,从该对象获取关联的std::future对象,启动线程并且传入std::promise对象的指针,调用std::future对象的get()函数阻塞等待,如果返回,那么打印输出返回的字符串信息。

 

基于C++模板,实现三种异步收发数据的方法

3、运行程序,输出的信息如下所示,从这里可以看出,std::promise在线程中设置值之后,std::future对象的get()函数成功获取并返回。

 

基于C++模板,实现三种异步收发数据的方法

二、通知线程退出

基于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发送的信号,那么退出循环,同时线程也退出了。

 

基于C++模板,实现三种异步收发数据的方法

2、创建std::promise对象,从std::promise对象提取关联的future对象,启动线程,并且将上面的future对象传递给线程,主线程休眠一段时间之后,调用std::promise对象的set_value函数来发送信号,通知线程退出

 

基于C++模板,实现三种异步收发数据的方法

3、从输出的结果信息看,线程一直在运行,当收到std::promise对象发送信号的信号之后就退出

 

基于C++模板,实现三种异步收发数据的方法

三、异步收发数据

经过上面两个例子的讲解,相信大家对std::future和std::promise已经有了一个大概的了解。下面就给出异步收发数据的模版类。

1、类模版JAsyncSender实现两个函数,一个是Send用于发送数据,它可以在线程中执行,另一个是Wait等待接收数据,如果第三个参数没有输入,那么默认一直等待,否则在指定时间内,没有收到信息,那么返回失败

 

基于C++模板,实现三种异步收发数据的方法

 

基于C++模板,实现三种异步收发数据的方法

 

基于C++模板,实现三种异步收发数据的方法

2、接下来说明类模版JAsyncSender的使用方法

定义成员变量m_AsyncSendInt,它由主线程和子线程共享。JAsyncSender的type为整型,也可以定义为字符串,甚至是自定义对象,根据具体需求场景具体定义。

 

基于C++模板,实现三种异步收发数据的方法

通过lambda方式创建线程,当然你也可以使用其他方式,线程内部先休眠一段时间,然后发送数据。

 

基于C++模板,实现三种异步收发数据的方法

从运行结果看,基于future和promise实现的异步收发数据模版类的功能是正常的。

 

基于C++模板,实现三种异步收发数据的方法

四、总结

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对象。

责任编辑:未丽燕 来源: 今日头条
相关推荐

2022-11-30 15:15:48

2024-01-24 11:44:44

C++智能指针开发

2010-02-03 15:46:15

C++函数传递

2020-11-01 17:10:46

异步事件开发前端

2023-10-28 16:25:17

滤波C++

2021-07-13 12:31:27

IT组织改进首席技术官

2015-12-11 09:24:38

加密数据Linux

2022-08-02 13:56:37

C开发段错误

2010-07-19 14:43:21

SQL Server查

2021-10-09 06:59:36

技术MyBatis数据

2023-05-16 16:07:07

大数据数据管理工具

2010-10-20 13:52:07

SQL Server数

2024-02-26 13:47:00

C#Socket数据接收

2010-02-04 10:33:40

C++异常传递

2013-01-04 15:47:54

Android开发平铺UI设计

2009-09-08 10:37:57

C#遍历CheckBo

2009-08-26 18:10:44

C# using的用法

2009-07-30 16:27:33

C#比较时间

2009-07-08 12:56:32

编写Servlet

2010-10-13 11:19:11

MySQL数据文件
点赞
收藏

51CTO技术栈公众号