需求场景大概是这样的
主控给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去取得数据