我有一个产生数据流的仪器;我的代码通过回调访问这些数据onDataAcquisitionEvent(const InstrumentOutput &data)
。数据处理算法可能比数据到达的速度慢得多,所以我不能希望处理每一条数据(我也不必),但希望处理尽可能多的数据。感谢该仪器作为环境传感器,具有我无法控制的数据采集速率。InstrumentOutput
例如,可以是一个包含不同位置的三个同时压力测量值的类。
我还需要保留一些简短的数据历史记录。例如,假设我可以合理地希望每 200 毫秒左右处理一次数据样本。大多数时候,我很乐意只处理最后一个样本,但有时我需要查看在最新样本之前到达的几秒钟的数据,具体取决于最后一个样本中是否存在异常读数。
另一个要求是尽快退出onDataAcquisitionEvent()
回调,以避免传感器中的数据丢失。
数据采集库(第三方)在单独的线程上收集仪器数据。
我想到了以下设计;拥有单个生产者/单个消费者队列,并将数据令牌推送到 onDataAcquisitionEvent() 回调中的同步队列中。
在接收端,有一个循环从队列中弹出数据。由于数据到达率很高,循环几乎永远不会休眠。在每次迭代中,都会发生以下情况:
- 从队列中弹出所有可用数据,
- 弹出的数据被复制到一个循环缓冲区(我使用了 boost 循环缓冲区),这样一些历史总是可用的,
- 处理缓冲区中的最后一个元素(并可能查看之前的元素),
- 重复循环。
问题:
- 这种设计是否合理,有哪些陷阱?和
- 有什么更好的设计?
编辑:我想到的一个问题是当循环缓冲区的大小不足以容纳所需的历史时;目前我只是重新分配循环缓冲区,使其大小增加一倍。我希望我只需要这样做一两次。