gpt4 book ai didi

c++ - QwebSocket::sendTextMessage/textMessageReceived 是异步的还是我不应该理会 QMutex/QEventLoop?

转载 作者:搜寻专家 更新时间:2023-10-31 01:35:50 31 4
gpt4 key购买 nike

我正在尝试通过 QWebSocket 发送和接收消息,但不确定这一切在“用户同时按下所有按钮”场景中的安全性。

想象一下:有几个按钮触发通过 QWebSocket 发送的消息,它们接收并处理响应,然后显示结果。 sendTextMessagetextMessageReceived 之间是否存在竞争条件,即几乎同时发送两条消息可能会触发响应混合?

我想问的是我是否需要这个:

// 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/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com