应该如何读取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 字节标头,但随后永远不会从 readRawData()
返回。
如果我添加...
if (m_socket->bytesAvailable() < 5)
return;
。到此功能的开头,应用程序工作正常(带有简短的测试消息)。
我猜测(文档非常稀疏)发生了某种死锁,我必须使用bytesAvailable()
信号逐渐建立缓冲区而不是阻塞。
这是为什么呢?从QLocalSocket读取的正确方法是什么?
您的循环会阻止事件循环,因此如果所有数据都没有到达 pn 第一次读取,您将永远不会获得数据,我认为这是导致您的问题的原因。
正确的方法是使用信号和插槽,在这里readyRead
-signal,然后读取插槽中的可用数据,如果没有足够的数据,则缓冲并返回,并在获得下一个信号时读取更多。
小心这种替代方法:如果您绝对确定您期望的所有数据都会及时到达(对于您同时控制客户端和服务器的本地套接字来说可能并非不合理),或者如果整个事情都在线程中,没有其他内容,那么使用waitForReadyRead
方法可能是可以的。但是事件循环将保持阻塞状态,直到数据到达,例如冻结 GUI(如果在 GUI 线程中),并且通常很麻烦。
相关文章:
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 使用 std::async 时死锁,将来作为成员
- 如何调试读写器锁的死锁?
- 为什么在Visual Studio 2013上的std::this_thread::sleep_for上死锁
- localtime() 函数正在调用 ___lll_lock_wait_private(),这会使线程陷入死锁
- 如何重现 Boost 进程文档提示的死锁?
- 多线程Windows GUI应用程序中的死锁
- 为什么printf会导致与future.get的死锁,而cout则不会?
- C++中具有阻塞队列和障碍的死锁
- 死锁使用 std::mutex 来保护多个线程中的 cout
- 避免并发等待对象中的死锁
- 在VC++中从DLLMAIN内部调用D3D的CREATEDEVICE时,它会创建一个死锁(loaderlock?)。有没有办法克服这个问题?最终目标内
- 当用2个螺纹锁定时,将recursive_mutex死锁
- 程序在 C++11 中使用条件变量进入死锁
- 一个线程提升的死锁
- 单个生产者/多个消费者死锁
- 当被调用方法使用调用方已锁定的同一锁时,如何避免死锁
- 应该如何读取QLocalSocket/QDataStream以避免死锁