在Qt中进行跨线程通信的类设计

4

问题陈述:使用摄像头跟踪对象并相应地移动方位和俯仰。

过程:摄像机获取对象的图像...每个摄像头帧都经过处理以找到(预期跟踪的)对象,每个帧生成的信息会传递给机械设备(万向架...),以便在平移和倾斜方面移动相机...

设计:主要的 Gui 在一个线程中运行,摄像头和万向架在另外两个线程中运行...在摄像头线程中产生的信息被传递到万向架线程,并且同一线程(即摄像头线程...)显示跟踪图像...

限制条件:显示速率比万向架移动速率快...所以在每个帧中...

  1. 帧被处理并显示(速率为10毫秒)
  2. 生成的信息被传递到万向架
  3. 暂停万向架线程更长时间(100毫秒),以便给机械部件足够时间移动,确保直到完成其移动之前没有新的更新进入万向架...

以下图表显示了 Qt 中的类设计及信号与插槽连接。

enter image description here

如有可能,请建议更好的解决方案...

错误:有时我会遇到一个错误...

QObject::killTimers: timers cannot be stopped from another thread


请注意,GUI 只能在主线程中工作,相机线程不应该在自己的线程中绘制任何屏幕内容(除非您使用一些独立于 Qt 的绘图机制)。 - Lol4t0
如果我不在其他线程中将画面绘制到屏幕上,那么假设我需要暂停相机...如果显示在GUI主线程中进行,则主线程会停止并且GUI会冻结...是的,GUI仅在主线程中工作... - rotating_image
1个回答

0
对我来说,你应该避免在线程之间调用这样的函数, 这是一个想法,这是我安全交换大量数据的方式。
你应该有一个状态机,两个线程都可以访问共享锁定变量(指向ping或pong缓冲区的主线程使用的指针+用于锁定的互斥体)
这样你就可以改变使用数据的方式,“显示”始终应该使用相同的指针。 开始读取时应获取锁定并在释放后释放。
相机应该写入另一个缓冲区 相机写入后,相机线程应尝试获取互斥锁的锁定,如果它获得了锁定(即另一个线程没有读取另一个缓冲区),则相机线程应获取锁定并更改由主线程使用的指针指向的缓冲区)
这样,您就没有线程之间的通信,只有互斥排除。
最大的风险是永远无法从相机线程中获取锁定,这里是一个解决方案-> 为了限制锁定时间,建议您在每个线程中都有第二个缓冲区,因此锁定时间将缩短到“memcpy”持续时间。 在结构中添加一个布尔值,表示相机是否更新了数据。
如果是的话,主线程会复制数据。 (在此期间相机无法交换指针),但一旦完成后,您的主线程也会将bool重置为false。 在此bool返回true之前,您不需要锁定以复制数据。 (现在这是无锁交换) 请注意,这仅在读取bool时是原子操作才成立。
希望能对您有所帮助。
(对我的英语表示抱歉)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接