本帖最后由 断点0216 于 2020-11-26 17:25 编辑
上一篇报告中,我将Zigbee协调器通过串口连接至MaaXBoard,并通过c编写的串口程序读取到了数据,而在界面显示部分,我用Qt实现了仪表和曲线。考虑到程序前后端功能的分离和程序解耦合,我尝试通过共享内存的方式实现界面程序和数据处理程序之间的数据交互。 共享内存我使用了Qt的QShareMemory,主要考虑到跨平台移植比较方便。程序我参考了Qt官方给出的demo例程(windos系统中Qt Creator的首页搜索可以找到。在Qt的),但是始终感觉不是太好用。例如我用python程序和Qt程序互相读写共享内存,python能正常读取到Qt写入的数据,但是Qt不能读取python写入共享内存的数据。另外,在Qt程序中,基于同一个句柄操作共享内存时,读取一次后,内存数据会被清空。
针对同一个句柄读写内存出现的问题,我的解决办法自然是同时声明读句柄和写句柄。如图中所示。两个对象在创建的时候会指向同一个共享内存映射文件。
共享内存类中做了如下定义。首先说明一下,针对同一个共享内存,我是定义了1000点数据,每个点的数据格式为单精度浮点型。每一个点可以对应一个传感器数据。用户级接口函数是WritePoint和ReadPoint。通过调用这两个函数,可以将指定点的指定数据写到共享内存。ThreadTest类中的信号函数trig()是用来通过多线程触发SharedMemory类中的槽函数loadFromMemory(),该函数每执行一次会对内存执行一次全部读取操作,并将数据解析到点的缓存PointBuffer中。
读写共享内存函数的如下。都是通过流操作完成,这里有个不友好的操作,QShareMemory的写操作,每次执行的时候都要create一下大小才行,并且还不能从偏移位置写入,不知道是不是我理解有误。
提供的读写点的函数,貌似有点太简单了
最后怎么用呢?我在窗体初始化中初始化了读写共享内存句柄,通过moveToThread方法将读内存函数加入到了独立线程,同时启动定时器,定时器中定时触发信号函数,同时执行写点和读点,这样,读写点的函数就被跟内存数据关联起来了。
看看运行效果,为了测试的方便,我的读写操作在同一个进程中完成了,如果想要在多进程中操作,拷贝代码,重新生成一个exe即可。这就是我下一步进程间数据交换要做的事了。
|