应该如何阅读QLocalSocket/QDataStream以避免死锁?

问题描述:

应该如何阅读QLocalSocket/QDataStream?应该如何阅读QLocalSocket/QDataStream以避免死锁?

我有一个程序可以通过命名管道使用QLocalSocketQDataStream与另一个进行通信。下面的recieveMessage()插槽连接到QLocalSocketreadyRead()信号。

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线程中),并且通常很麻烦。

+0

谢谢,我没有想到它是* my * loop阻塞(尽管我看到它在调试器中旋转!)而不是readRawData()。 – sebf