我的系统有多个采样数据线程,将采集到的数据需要上传到本地显示屏和远端控制中心,那这多个采样线程怎么和这两个显示线程通信呢?
采用邮箱+内存池的话,如果创建一个邮箱,那优先级高的显示线程拿到数据后,内存池的动态内存就释放掉了。另外一个显示线程就拿不到数据了,消息队列的方式也是一样的情况。这种情况是要创建两个邮箱+内存池或者两个消息队列嘛?采集线程采集到数据把同一个数据分别存入两个邮箱,然后显示线程去读取,是这种方法吗?如果不是,那有什么好的方法吗?
我有四个采样线程,那这四个采样线程的数据是每一个线程创建两个邮箱给到显示屏吗?如果是这样的话,那每个显示屏需要等待4个邮箱,那会不会有问题呢?有什么好的解决方式嘛?
如果不采用消息队列或者邮箱+内存池的方式,那可以使用事件集的方式嘛?每个采样线程创建一个事件,当四个采样线程都采集数据完毕后,在显示屏线程判断事件,然后读取数据。这样的话,那采集的数据放到哪里啊,显示屏又该怎么读取呢?采用全局数组嘛?两个显示程序都去全局数组里面拿数据,这样的话,数据安全性和一致性有保证吗?
针对你题中的问题,我理解可以考虑使用事件驱动模型来处理。
我先简单画了下我的设计方案,仅供参考。
在参考这个图之间,建议先通读下这篇关于事件驱动的文章:干货 | 用FreeRTOS搭建Event-Driven应用框架
这个设计图体现的就是,4个采集线程共用2条消息队列,一条消息队列专供本地显示,另一条消息队列专供远端上传,这样可以把事件的处理解耦开来。
这个方案,有一点点的缺点就是,在同样的事件存在于2条队列中,稍微多耗了一些内存。
这个有一个前提,采样频度比较低,比如每秒不到 10 次。每通道采样一次耗时比较集中而且很快,例如 spi 或者 iic 接口和 adc 这种方式。可以四个通道采样使用一个线程,四个通道挨个采样,采样线程给其它线程挨个发信号,之后进入几十毫秒的延时休眠,等待下次采样。
如果采样比较频繁,每秒几十次。可以把采样数据放到共享内存(全局变量内存),显示线程定时间隔刷新界面从共享内存获取数据刷新显示。要求每次采样都上传,就每次采样单独给上传线程发信号,然后上传线程去共享内存获取数据。
线程不要太多,信号、队列也不要太多。采样频度低的时候也可以这么做。
一个通道一个采样线程的方式,线程数量有点儿多,很难保证四个通道的数据同步,有可能采样间隔比较长,比一个线程挨个采样四个通道使用的时间长。
那我的采集线程采集的数据放哪里呢?全局数组里面吗?采集线程采集完然后放数组里面,向消息队列发送事件,事件消费者监听,根据产生的事件去取数据。是这样吗?
@吕蛋蛋 采集的数据肯定是要buffer里面,看你的的采样数据一次有多大,如果很大的话,不建议使用全局buffer,因为这就意味着这段内存就常驻了,没有释放,比较建议使用堆空间。
针对这个问题:
采集线程采集完然后放数组里面,向消息队列发送事件,事件消费者监听,根据产生的事件去取数据。是这样吗?
—》是的,不过我需要说明下的是,总共只有2个队列,一个队列归本地显示管,另一个归远端上传管;4个采样线程都是往这2个队列发数据。可以仔细评估下我上面提供的架构图。