QLocalSocket/QDataStream应该怎么读才能避免死锁?
How should QLocalSocket/QDataStream be read to avoid deadlocks?
QLocalSocket/QDataStream应该怎么读?
我有一个程序使用 QLocalSocket
和 QDataStream
通过命名管道与另一个程序通信。下面的 recieveMessage()
插槽连接到 QLocalSocket
的 readyRead()
信号。
void MySceneClient::receiveMessage()
{
qint32 msglength;
(*m_stream) >> msglength;
char* msgdata = new char[msglength];
int read = 0;
while (read < msglength) {
read += m_stream->readRawData(&msgdata[read], msglength - read);
}
...
}
我发现应用程序 有时 在 readRawData()
上挂起。也就是说,它成功地读取了 4 个字节 header,但之后从未从 readRawData()
.
中读取 returns
如果我添加...
if (m_socket->bytesAvailable() < 5)
return;
...到此功能的开始,应用程序运行良好(带有简短的测试消息)。
我当时猜测(文档非常稀疏)发生了某种死锁,我必须使用 bytesAvailable()
信号逐渐建立缓冲区而不是阻塞。
这是为什么?从 QLocalSocket 读取的正确方法是什么?
你的循环阻塞了事件循环,所以如果所有数据都没有到达 pn first read,你将永远不会得到数据,我认为这就是导致你问题的原因。
正确的做法是使用signals和slot,readyRead
-这里是signal,读取你slot中可用的数据即可,如果不够就buffer一下然后return,再读取当你收到下一个信号时更多。
小心使用这种替代方法: 如果您绝对确定您期望的所有数据都会及时到达(对于您控制两个客户端的本地套接字,这可能不是不合理的)和服务器),或者如果整个事情都在一个什么都不做的线程中,那么使用 waitForReadyRead
方法可能没问题。但是事件循环将保持阻塞直到数据到达,例如冻结 GUI(如果在 GUI 线程中),并且通常很麻烦。
QLocalSocket/QDataStream应该怎么读?
我有一个程序使用 QLocalSocket
和 QDataStream
通过命名管道与另一个程序通信。下面的 recieveMessage()
插槽连接到 QLocalSocket
的 readyRead()
信号。
void MySceneClient::receiveMessage()
{
qint32 msglength;
(*m_stream) >> msglength;
char* msgdata = new char[msglength];
int read = 0;
while (read < msglength) {
read += m_stream->readRawData(&msgdata[read], msglength - read);
}
...
}
我发现应用程序 有时 在 readRawData()
上挂起。也就是说,它成功地读取了 4 个字节 header,但之后从未从 readRawData()
.
如果我添加...
if (m_socket->bytesAvailable() < 5)
return;
...到此功能的开始,应用程序运行良好(带有简短的测试消息)。
我当时猜测(文档非常稀疏)发生了某种死锁,我必须使用 bytesAvailable()
信号逐渐建立缓冲区而不是阻塞。
这是为什么?从 QLocalSocket 读取的正确方法是什么?
你的循环阻塞了事件循环,所以如果所有数据都没有到达 pn first read,你将永远不会得到数据,我认为这就是导致你问题的原因。
正确的做法是使用signals和slot,readyRead
-这里是signal,读取你slot中可用的数据即可,如果不够就buffer一下然后return,再读取当你收到下一个信号时更多。
小心使用这种替代方法: 如果您绝对确定您期望的所有数据都会及时到达(对于您控制两个客户端的本地套接字,这可能不是不合理的)和服务器),或者如果整个事情都在一个什么都不做的线程中,那么使用 waitForReadyRead
方法可能没问题。但是事件循环将保持阻塞直到数据到达,例如冻结 GUI(如果在 GUI 线程中),并且通常很麻烦。