在Qt线程之间共享数据

5

我对Qt不熟悉,请原谅问题的简单性,但是我对Qt线程有点困惑。 假设我有3个线程:默认GUI主线程和我自己创建的2个线程(称为WorkerThread)。 我的每个WorkerThread都继承自QThread,它们是永久线程,每隔一段时间就会唤醒并通过套接字发送数据,并在GUI元素上发布状态。如何最好地实现以下目标:1)允许GUI线程设置WorkerThread对象中可用的数据? 2)允许WorkerThread向GUI线程发送状态以供用户显示? 3)允许两个WorkerThread使用同一个套接字?

从文档中看来,当我创建WorkerThread对象时,它由创建线程拥有(除了run方法是新线程)。那么如何为新线程设置要执行的数据? 新线程使用的所有数据都必须是全局的吗?例如,我希望GUI允许用户选择每个WorkerThread发送的数据包类型。 我曾经认为,我会在WorkerThread中放一些槽,GUI线程将发出信号。 当WorkerThread对象收到SetPacketType信号时,它会设置成员变量,该变量在每次迭代时被引用。但是,阅读完文档后,我不确定是否应该这样做。如果WorkerThread对象由创建线程(在此情况下为GUI线程)拥有,则向其发送信号是否会跨越线程边界?

另外,共享套接字连接的正确技术是什么?

提前感谢。


3
Qt会自动将线程之间的信号和槽转换为QEvents,QEvent基于操作系统事件系统提供了安全的线程数据交换方式。你也可以发送自定义事件,但信号/槽更易于使用。在不同地址空间的情况下,共享任何对象(或指针/引用)跨线程是无效的。你只能复制一些数据并通过事件进行发送。 - Pie_Jesu
1个回答

4
使用Qt,在线程之间发送信息的最简单方法是使用信号和槽。Qt自动为线程之间的连接使用排队信号(参见Qt::ConnectionType),这确保了一个信号可以从一个线程发出,但插槽将在接收对象的线程中执行。
如果在线程之间发送的数据(要执行的工作或状态信息)是Qt可以自动排队的内容(例如QString、内置类型如int和double等),那么将信息作为信号/槽的参数传递是发送信息的最佳方式。如果共享的数据很大或复杂,则需要使用qRegisterMetaType允许Qt复制数据,或者传递指向线程安全对象的指针。与Pie_Jesu所说的不同,线程确实共享地址空间,因此您可以共享指针;只需确保一个线程与共享对象的交互不会干扰另一个线程的交互即可。

QTcpSocket 不是线程安全的(根据Qt的文档,它只是可重入的),因此如果您共享套接字,则需要负责确保线程不以冲突的方式使用套接字。


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