- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试通过 QWebSocket 发送和接收消息,但不确定这一切在“用户同时按下所有按钮”场景中的安全性。
想象一下:有几个按钮触发通过 QWebSocket 发送的消息,它们接收并处理响应,然后显示结果。 sendTextMessage
和 textMessageReceived
之间是否存在竞争条件,即几乎同时发送两条消息可能会触发响应混合?
我想问的是我是否需要这个:
// somewhere in initialization code, I have it in a slot connected to the QWebSocket's "connected" signal
connect(&socket, &QWebSocket::textMessageReceived, this, &client::record_response); // store the response in a member QString called "response"
connect(&socket, &QWebSocket::textMessageReceived, &wait_for_it, &QEventLoop::quit);
// somewhere after a button is pressed
mutex.lock()
socket.sendTextMessage(message);
eventLoop.exec()
QString the_response = response;
mutex.unlock()
// continue working with the_response
或者如果设置更简单(没有互斥量也没有事件循环):
// initialization after QWebSocket is connected
connect(&socket, &QWebSocket::textMessageReceived, this, &client::record_response); // store the response in a member QString
// somewhere after a button is pressed
socket.sendTextMessage(message);
// continue processing "response" immediately
在调用 sendTextMessage
之后,QString 响应
会立即“填充”吗?我不这么认为,但这意味着所有 QWebSocket
机制都是异步的,我无法在其文档中明确找到这一点。那么我应该怎么做才能防止竞争条件呢? (我能不能让它更简单,这样我就不需要任何“中间”变量,比如 response 和 the_response,或者事件循环?)
编辑 我看到了 this question (更重要的是 this answer )在侧边栏中链接,这让我想到我可以只使用 lambda 而不是整个设置,但也许将互斥锁作为一种简单但相对昂贵的方式来防止之间的串扰响应和请求。这有什么意义吗?
最佳答案
Qt 的 I/O/网络相关类(包括 QWebSocket)是异步的,以避免阻塞主线程,但绝不会向 API 用户公开它们可能在内部使用的任何多线程。因此,除非您在自己的代码中使用线程,否则只有极少数情况会使用 QMutex 或其他显式线程同步(我唯一想到的是 QtQuick 项目的自定义绘制)。
textMessageReceived
将在任何其他事件(其中的用户输入)之间按事件循环管理的顺序发出,但绝不会以并行、多线程的方式发出。
正如您已经注意到的,QWebSocket 不提供一种机制来跟踪哪个响应属于哪个请求。互斥量对您没有帮助,阻塞执行是 UI 编程中的错误方法。您不希望用户界面在等待响应时卡住。根据您的用例,您可以禁用 UI,例如在等待响应时通过模态进度弹出窗口或 setEnabled(false)(如果使用小部件),确保在 UI 等待第一个响应时不会发送第二个请求。现在这仍然比完全阻塞 UI 线程要好,后者甚至会阻止 UI 被绘制。
如果您希望 UI 保持启用状态并可能在等待对先前请求的响应时发送更多请求,则需要围绕 QWebSocket 构建自定义“请求管理器”逻辑,将响应与请求匹配,跟踪未响应请求的队列并在响应到达时通知正确的请求发送者。我的建议是遵循 QNetworkAccessManager 中也使用的命令模式(QNAM):发送请求时,向发送者返回一个 Reply 对象(在 QNAM 中,即 QNetworkReply 的作用)。发件人连接到回复的“完成”信号,一旦相应的响应到达,就会发出该信号。这样,发送方就会以事件驱动的异步方式准确接收到想要的响应,而无需任何显式等待和阻塞。
关于c++ - QwebSocket::sendTextMessage/textMessageReceived 是异步的还是我不应该理会 QMutex/QEventLoop?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36670355/
我有一个属于某个类的函数,在这个函数中,函数开头有一个 mutex.lock,返回前有一个 mutex.unlock。现在遇到了mutex卡在locked状态的情况。如果此功能是我使用该互斥锁锁定和解
给定以下代码: #include #include #include #include #include #include #include #include #include #i
假设有如下QT代码(QT 5.3.1): void SenderClass::runSignal() { emit mySignal(); } void ReceiverClass::Rece
从不同的线程写入共享变量,我计划使用 QMutex,如果我将互斥变量声明为外部变量,我可以使用它在来自不同源文件的单独两个函数中进行读写吗? 喜欢 header.hpp extern QMutex m
我通过通常受相应互斥锁保护的公共(public)可访问成员变量来命令我的线程。 我的问题是:如果单个变量在写访问期间受互斥量保护它是否也应该在读取访问期间受到保护,还是我可以简单地读取它? 示例: 一
我正在尝试使用递归 QMutex,我阅读了 QMutex 类引用,但我不明白如何去做,有人可以给我一个例子吗?我需要一些方法来锁定可以在调用锁定方法之后或之前解锁的 QMutex。如果递归互斥不是这种
我是 Qt 的新手,我正在寻找 Qt 中的多线程。 正如我在 Qt Documents 中了解到的那样,我为两个线程定义了两个类: #include #include class thread_a
我只想实现如下代码。 QString Class1::getNonce() { //if some thread is getting nonce wait here until it fin
我已经包含了 QMutex header 并使用它,如下所示。但是我收到以下错误: error C2146: syntax error : missing > ';' before identifie
你好,我在用 qmutex 掌握 qthread 时遇到了问题——通常如何使用它——学习它我正在尝试创建限制为 8,000,000 的质数搜索器,但即使我使用给定的代码作为基础,我也失败了对于类似的例
从多个线程调用以下追加函数。我不希望数据重新写入追加,因为计数器尚未递增。 这会暂停所有进入的线程,除了当前使用 Append 的线程吗?或者其他线程会继续运行而不附加数据吗? 互斥量是否需要是“ST
我发现即使是对 QMutex 的简单等待也会导致断言。我可能做错了什么? QMutex mutex; SyncMgr::SyncMgr(QObject *parent) : QObject(paren
有没有人知道如何在不使用函数的情况下检查 QMutex 是否被锁定: bool QMutex::tryLock() 我不想使用 tryLock() 的原因是因为它做了两件事: 检查互斥锁是否被锁定。
在 Qt 文档中关于 QMutex据说: (...) When you call lock() in a thread, other threads that try to call lock() i
我有一个非常简单的情况:我在一个线程中有一个高速数据生成器,该线程生成其中包含[可变长度]元素的缓冲区。一旦缓冲区被填满,我就拥有一个将其写入磁盘的使用者。 现在,如果尚未由使用者线程写入缓冲区,则需
我有一个 C++ Qt 程序,它使用 QThread 和使用 QMutex 和 QWaitCondition 实现的暂停/恢复机制。这就是它的样子: MyThread.h: class MyThrea
我正在尝试向我的 Qt 应用程序添加多个线程,但是当它执行这个线程时,程序就崩溃了,我得到了一个错误 QThread: Destroyed while thread is still running
我想知道关于 Mutex 的哪种用法更好。我想到的两种用法是: 1) Qlist getList() { QMutexLocker locker(&m_mutex);
我有 QMutex m_mutex; 作为我类(class)中的私有(private)字段,我尝试使用其中一种方法中的 QMutexLocker 锁定它,但是当我尝试构建它时,我得到 C2530 错误
我正在GDB中运行我的程序。我的程序需要为其工作创建16个线程。所有这些都很好。最后我得到了错误QMutex::lock: Deadlock detected in thread 0xfe8这是GDB
我是一名优秀的程序员,十分优秀!