c++thread学习(3)并发多线程系统开发过程


 

在实现一个规模较大的工程时,需要多个线程之间互相传递数据,因此,点对点的通信机制已经不能满足需要,设定一个比较合理的通信架构会提高工程开发、维护的效率以及代码的复用性,可读性。

了解ROS的小伙伴都知道,ROS的通讯是   节点——话题——节点   的方式。每个节点代表一个可执行模块,每个话题是一块通信数据内存,节点之间的通讯通过话题这个“中介”传递(消息)。节点之间的通信方式是,生产者(节点)发布消息(通信数据)到话题,需要此数据的消费者(节点)通过订阅此消息完成通信。这种通讯方式又叫做分布式通讯,各个节点之间没有耦合关系。由上面简述可知,ROS的通讯机制比较合理,因此,在我们开发一个比较大的工程时,怎么实现这种通讯机制?下面以作者本人开发工程的经验,给出一个利用多线程开发一个较大工程的过程。

 

一:分析系统功能要求,确定工程代码需要几个线程。

     这一步十分重要,其决定着整个工程的框架,因此,在设计整个代码之前,一定要弄清楚工程需要几个线程实现,一般来说,一个线程实现一个独立的模块功能。需要说明的是,线程不是越多越好,除了内存,线程间资源竞争外,操作系统、CPU也会对线程数限制。

二:根据各个线程的之间的关系决定需要通讯的数据,画公共数据区和每个线程的数据流图

公共数据区存放着整个系统通讯的数据,是数据传输的一个枢纽。这一步是直观的画出数据与各个线程的通讯图,通过画这个图,使开发者更清楚的明了系统数据在各个线程的流向,更方便设计各个线程流程。比如,作者本人开发的系统数据流图如下:

图1 公共区数据与各个线程通讯数据流图

从图1可以清楚的看出,公共区数据与各个线程的交互。比如,对点云去噪线程而言,其只需要从公共数据区获取1相机参数和2图源缓存(类似于ROS的订阅),然后处理完放入把3去噪结果放入公共区(类似于ROS的发布)。

三:设计实现公共区。

类似于ROS的话题,这一步是建立一个公共通讯内存。为了存储数据以及通讯的方便,用一个类来管理这些通信数据。这个类中不但包含所有通信数据(图一),还包含所有数据的读写方法(图二),类似于ROS的发布和订阅消息。数据设计如图,对于每个通信数据,弄清楚其生产和消费者。


 

图二 公共区数据

公共区数据的管理方法

图三 公共区数据通信(读写)管理

 

四:设计每个线程的流程图

每个线程都是一个死循环,根据系统的功能设计各个线程流程,比如系统何时模式切换、休眠等待等。

 

五:设计每个独立的功能模块,封装成类,并测试。

若干个独立模块是组成系统的核心部分,把各个独立的功能模块设计成类的好处是:

1:可以方便实例化测试各个功能模块。

2:方便模块的移植、重复利用。

对于每个独立的模块,编写一个测试用例,用来测试其实现功能是否符合预期。

六:编写各个线程的代码并测试

对于各个线程:

在死循环外,实例化功能模块类;

在死循环内,循环执行从公共区获取数据->调用方法->发布结果或切换模式。

七:整合调试系统

在主线程里实例化公共区,并把公共区地址传入各个线程。首先在主线程里逐一开启各个线程,测试功能是否与预期一致;然后开启各个线程,调试系统。



 

posted on 2017-06-08 16:07  从小白做起  阅读(288)  评论(0编辑  收藏  举报