在Qt阻塞主机示例中使用互斥体
Use of Mutex in Qt Blocking Master example
我正在研究Qt阻塞大师的例子,以了解使用Qt进行串行通信。在此示例中,串行通信以同步方式完成,因此,为了保持 GUI 响应,创建了一个单独的(非 GUI(线程来处理串行通信。我不明白的是负责通信的线程中使用互斥锁的部分(即MasterThread
( 同步线程:
注意,transaction(( 方法是在主线程中调用的,但是 请求在主线程线程中提供。主线程数据 成员在不同的线程中同时读取和写入,因此 QMutex 类用于同步访问。
void MasterThread::transaction(const QString &portName, int waitTimeout, const QString &request) { QMutexLocker locker(&mutex); this->portName = portName; this->waitTimeout = waitTimeout; this->request = request; if (!isRunning()) start(); else cond.wakeOne(); }
[主线程运行方法]
void MasterThread::run() { bool currentPortNameChanged = false; mutex.lock(); QString currentPortName; if (currentPortName != portName) { currentPortName = portName; currentPortNameChanged = true; } int currentWaitTimeout = waitTimeout; QString currentRequest = request; mutex.unlock();
在任何情况下都不应调用 transaction(( 方法 同时与获取数据的进程同时进行。注意,虽然 QString 类是可重入的,它不是线程安全的。因此,它不是 建议读取请求线程中的串行端口名称,以及 超时或请求另一个线程中的数据。MasterThread 类可以 一次只处理一个请求。
我的问题:
-
我不明白需要互斥体。我的推理是只有一个线程(在
Dialog
类中创建(处理通信,因此没有竞争条件,也不需要同步。 -
我对上面引用的最后一句话感到更困惑(即"在任何情况下......"(。"[另一个]进程获取数据"是什么意思?我们这里只有一个进程(即整个应用程序(和两个线程(一个用于 GUI,一个用于串行通信(,而这两个线程没有共享数据,这不是真的吗?为什么
QString
的线程安全在这里很重要?
我不明白需要互斥。我的推理是只有一个线程(在 Dialog 类中创建(处理通信,因此没有竞争条件,也不需要同步。
应用程序从一个已处于活动状态的线程启动。这就是 gui 线程。一旦启动其他线程,就会有多个线程。如果通信线程与其他线程隔离,它将毫无用处。一旦它不再被隔离,就需要一种同步访问共享数据的方法,并且必须共享一些数据 - 这就是没有隔离的定义。取消隔离线程的唯一方法是共享一些数据(如果未使用操作系统或硬件可能提供的低级消息传递功能 - 在这里,它没有(。
同步在 gui 线程和通信线程之间进行。transaction()
方法必须是线程安全的,即它必须使用一些同步原语 - 这里为互斥锁。
"[另一个]进程获取数据"是什么意思?
该过程在特定句子中用作线程的不幸同义词。
为什么QString的线程安全在这里很重要
QString
的线程安全性很重要,因为一次只能从一个线程访问特定的QString
实例,即不支持并发性。甚至不支持读取并发 - 有些人认为仅仅因为他们不修改数据,只读访问就是线程安全的。除非明确指定,否则不会如此。具体来说,在这种情况下:在线程 1 中读取给定的QString
,并在线程 2 中写入它,会导致未定义的行为,这不是假设的。你会破坏东西。
这两个线程没有共享数据
进程的线程都位于同一地址空间中,因此默认情况下共享数据。因此需要同步原语。同步可能是隐式的,例如,如果线程通过发布事件进行通信,则事件队列是同步原语:它将从事件发布者到事件接收器的访问序列化,即针对给定线程的事件发布者与该线程中的接收器同步。
- Qt VTK交互风格的信号到小部件
- QT在错误的班级中寻找空位
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 如何在Qt窗口小部件中使用QStringView(或QStringRef)
- 如何在Qt C++中更改光标
- 如何在MS Visual Studio 2019中运行QT UI
- QT通过C++添加映射QML项目
- libssh 的函数在构建 libssh 时无法在 Qt 和 cmake 错误中找到
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 使用Qt C++计算类似Git的SHA1哈希
- Qt focusObjectChanged example?
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- C++ / Qt:如何检测主机名或IP地址何时引用当前系统?
- 在Qt阻塞主机示例中使用互斥体
- 将二进制数据从Qt/C++DLL传递到Delphi主机应用程序中
- 如何使用Qt获取主机名
- 在主机应用程序中使用Qt用户界面
- 如何在qt中解析网络主机名+端口
- Qt - 从IP Adreess获取主机名和MAC地址