• 使用std:promise std::future 实现HTTP接口 耗时操作的的同步返回


    需求场景大概是这样的

    主控给rk1126发送一个http post请求,请求的内容是一张jpeg图片 

    rk程序这边收到这个图片之后 需要对图片进行ai分析 然后返回结果给主控 

    http使用的是libevent库实现的

    一般http都是短链接,大多数的使用场景都是收到这个请求之后就返回了 回给服务器一个代码表示我收到这个请求了 之后 服务器会再次下发一个get请求 查询 服务状态 什么的 

    但是呢 由于我们这个ai分析时候异步的耗时操作,主控也不提供异步查询接口,这就要求我们将异步的操作 模拟成同步的操作,就是主控给我传这个jpeg的图片之后 我的http线程不能退出,等待ai分析出来结果之后 将结果respone给主控再退出

    看下代码 注册一个文件上传的handler 标黄的这个函数

     QMCY_AIJPEGHandler函数用来处理上传jpeg图片时文件的提取并保存到本地 

    提取完之后  放到一个队列里面  主线程会从这个队列里面提取这个消息然后做ai分析

    然后重要的是 目前的这个线程不能退出 因为退出的话http的连接就关闭了 

    所以 必须得让这个线程阻塞在这 等待 ai分析的那个线程返回结果 并通知当前线程。

    正好这两天在看c++11的东西   c++11 提供的 std::promise和 std::future 很符合这个场景

    光从promise字义上看 很难让人想到这个 东西的作用 

    我也是刚接触 具体的功能百度可以搜到一大堆 

    简单描述就是 我先定义一个promise  然后 同时 设置一个future等待promise的返回

    先看定义的地方 存储了一个string用于存放返回结果

    设置完之后 将需要执行的操作放到一个队列 主线程将会从这个队列取出任务并执行 

    http线程值所以能实现阻塞就是因为 

    auto iVal = pHandle->exec_result.get(); 

    future的get操作会让当前线程阻塞 ,直到另一个线程将promise set了 

    这里之所以定义成指针形式 是因为 一个promise只能被设置一次 ,不然的话会报异常 

    我们这个接口是可以不断被调用的 所以 做成动态的一次调用之后就delete 

    有新的来就 new一个 这样 操作 

    这是http线程的代码 

    然后看下另一个ai分析线程的处理部分 如下:

    经过ai分析处理之后 也即 QMCY_JPEG_Analyze会返回一个pair的接口 first表示成功失败 second用于保存ai分析结果

    然后会将结果以json的形式构建出来  最重要的最后 

    pHandle->in_progress->set_value(content); 这个代码会使之前future从get那里返回 并继续往下执行 

    然后将结果回给服务器了  

    接昨天的  为了更好的理解std::future 

    看了另一篇博主的例子 

    同时引入std::future_status 等待ai分析的过程中 可以 

    之前的ai分析那块加了一秒的延时 如下:

    等待结果这里修改如下:

     

     

    然后看下程序执行结果:

    如下:

     

     这么更便于理解std::future  

    执行的过程中会每100ms去轮询 执行的状态  直到状态promise set_value之后 

    future的status会变成ready 说明执行完毕了 之后 通过future.get去取得数据

  • 相关阅读:
    CI/CD Jenkins容器化安装部署
    WebSocket的简单应用
    [附源码]java毕业设计毕业生离校管理系统
    马斯克又一壮举 发射420颗卫星组建互联网
    【TS04——接口的多态——泛型接口】
    F5 iRule示例综合展示
    smile——Java机器学习引擎
    Eye Tracking for Everyone
    C语言之预处理命令使用详解----#if、#endif、#undef、#ifdef、#else、#elif
    小程序 + dayjs自定义 picker 时间选择器
  • 原文地址:https://blog.csdn.net/baoecit/article/details/126018029