在不同的线程中使用QUdpSocket可以吗

Is it ok to use a QUdpSocket in different threads?

本文关键字:QUdpSocket 线程      更新时间:2023-10-16

我想要一个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在主线程中。这样可以吗?

但是,writeBytes在工作线程中,readBytes在主线程。这样可以吗?

如果您使用的是原始的POSIX套接字(例如int文件描述符和BSD套接字API的sendto((调用(,那就没问题了;然而,QUdpSocket派生自QObject,并且QObject不打算由多个线程同时访问。特别是,快速查看QUdpSocket::writeDatagram((方法的实现可以发现,该方法执行的操作包括底层套接字的延迟初始化、文件描述符的缓存和信号的发出,如果时间正确(错误?(,任何这些操作都可能与来自不同线程的同时非同步访问交互不良。你的代码可能会逃脱惩罚,但我不相信它能一直可靠地工作或在所有系统上工作。

我的建议是创建两个QUdpSocket对象,一个用于发送,另一个用于接收。这将确保避免比赛条件,并且额外的QUdpSocket对象并不是一个很大的成本来支付。