一个基于线程池的队列同步执行框架(C++) 一个基于线程池的队列同步执行框架(C++) 其实关于这篇文章的名字我想了很久,最终觉得怎么命名都不能完整的描述整个功能,所以索性我们在文章当中一块来体会吧。 这个框架是源于我们的传感器融合产品的开发过程中,所以在文章的一开始,我先来介绍一下应用此框架的算法模块的运行流程,下面呈上流程图:
算法流程 我们先同时三个传感器的原始数据,然后分别进行图像的推理和数据的处理,随后将处理的结果和原始数据一起抛入到融合算法模块中进行运算,最后输出结果,在一整个pipeline完成之后,再进行下一次同时传感器原始数据的操作。 在不借助任何外部框架的前提下,我们可能会想到用线程池来实现上述流程。 但是在实际的应用过程中,我们会遇到一个问题,第二队要同时执行的算法要怎么知道第一队已经全部执行完了呢,我们可能自然而然的会想到用锁和条件变量来解决上述问题,例如在短焦图像的到来之前,短焦推理的线程便一直在状态: 其它的算法模块调用也都按照类似的方式来编写。 融合算法的代码相对来讲就会臃肿一些,因为他需要等待三个线程全部执行完毕才能开始执行 这样写固然可以,但是代码的复杂度和对锁的管理足以让人头疼。 还有一个问题就是,如果算法工程师要增加或减少其中的算法模块,或者修改模块的执行顺序,要修改的代码量也是不少的,而且如果把锁搞错Debug起来也不是很方便。 所以我就想,可不可以写一个简单的框架来实现上述功能,于是便有了此框架。 接下来让我们进入正题。 开始介绍一下框架的用法并对关键代码进行说明。 我们先来看看框架在实际运用时长什么样子,例如我们还是上述场景,为了体会框架的用法,我们把流程简化一下,先同时三个传感器的数据,在同时对三种传感器的数据进行处理,随后进入融合算法,最后处理结果: 这样就简化了代码的编写,如果算法的整个pipeline有什么变动修改起来也很容易,如果完全实现文章一开始的流程也不难,最简单的方法就是将拿数据和处理该传感器数据的函数封装到一个函数中,在这里就不赘述了。 下面让我们来看看框架具体是怎么执行的,我们先从构造函数入手: 这里的是一个类型为的,构造函数的代码其实和线程池的代码完全一致,先根据我们的来创建个线程,当(类型为)中的任务为空的时候,我们创建的线程就在循环中,等生产者的到来并且检查中任务不为空的时候便开始执行中的一个任务,执行完毕后再将任务从中弹出,进入下一个循环。 接下来让我们看看函数: 是一个模板函数,返回值为你压入的任务函数的返回值,由于任务是异步执行的,所以我们用来接任务函数返回值。 在这里如果你是当前编号队伍中第一个入列的,那么会新建一个队列并将此任务压入进去,再将这个队列压入到总的队列vector (类型为)中,如果不是第一个入列的,那么我们直接压入到之前已经建好的对应编号的队列中就可以了,压入之后尝试通知函数开始执行,中会根据来确定是否所有任务都已压入完毕。 最后让我们看看start函数: 在这里我们将根据队列编号由小到大执行队列任务,在一个队列的执行过程中,我们先将该队列中任务的返回值压入到(类型为)中,随后将任务压入到真实的执行队列中(也就是之前构造函数中线程在等待的),然后开始执行该队列的任务,在下边的 中会检测是否该编号的任务全部执行完毕并返回,如果没有返回便在这里阻塞,如果都返回完毕便进入下一循环执行后一编号的任务。 至此框架的所有关键代码说明完毕,完整的Demo项目我会放到我的GitHub仓库中以供查阅参考:https://github.com/SRam0s/queue-frame 觉得有所启发的话就帮我点个star吧 :)
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/26616.html