我想要一个QUdpSocket但是在不同的线程中读/写数据如下:
void UDPLink::writeBytes(const char* data, qint64 size)
{
// Broadcast to all connected systems
for (int h = 0; h < hosts.size(); h++)
{
QHostAddress currentHost = hosts.at(h);
quint16 currentPort = ports.at(h);
socket->writeDatagram(data, size, currentHost, currentPort);
}
}
void UDPLink::readBytes()
{
while (socket->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(socket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
// FIXME TODO Check if this method is better than retrieving the data by individual processes
emit bytesReceived(this, datagram);
}
}
readBytes()
会触发套接字readyRead
信号。
但是writeBytes位于工作线程中,而readBytes位于主线程中。这好吗?
答案 0 :(得分:2)
然而,writeBytes位于工作线程中,而readBytes位于 主线程。这好吗?
如果您使用的是原始POSIX套接字(例如int文件描述符和BSD套接字API的sendto()调用),那就没关系;但是QUdpSocket派生自QObject,并且QObjects不打算同时被多个线程访问。特别是,快速浏览一下QUdpSocket :: writeDatagram()方法实现,可以看出该方法的作用如底层套接字的延迟初始化,文件描述符的缓存以及信号的发送,其中任何一个都可能与同时进行的交互不良给定正确(错误?)时序的不同线程的非同步访问。您的代码可能会随之而来,但我不相信它能够始终可靠地工作或在所有系统上工作。
我的建议是创建两个QUdpSocket对象,一个用于发送,另一个用于接收。这将确保避免竞争条件,并且额外的QUdpSocket对象不是一个非常大的成本,为安心而付出代价。