应该如何阅读QLocalSocket/QDataStream以避免死锁?
问题描述:
应该如何阅读QLocalSocket/QDataStream?应该如何阅读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个字节的标题,但从未从readRawData()
返回。
如果我添加...
if (m_socket->bytesAvailable() < 5)
return;
...这个功能的启动,应用程序工作正常(与短的测试消息)。
然后我猜测(文档非常稀疏),发生了某种类型的死锁,并且我必须使用bytesAvailable()
信号逐步建立缓冲区而不是阻塞。
这是为什么?从QLocalSocket读取正确的方法是什么?
答
您的循环会阻止事件循环,因此如果所有没有到达第一次读取的数据,您将永远无法获取数据,这是什么原因导致您的问题出现。
正确的做法是使用信号和插槽,这里是信号和插槽,只读取插槽中的可用数据,如果没有足够的数据,缓冲并返回,并在获得下一个信号时读取更多信息。
小心使用这种替代方法:如果你有绝对的把握你所期望的数据将(与你控制客户端和服务器的本地套接字也许不是不合理的)到达及时,或者如果整个事情是在没有别的东西的线程中,那么可以使用waitForReadyRead
方法。但事件循环将保持阻塞,直到数据到达,例如冻结GUI(如果在GUI线程中),并且通常很麻烦。
谢谢,我没有想到它是* my * loop阻塞(尽管我看到它在调试器中旋转!)而不是readRawData()。 – sebf