在不同的线程中使用QUdpSocket是否可以?

时间:2015-05-16 04:56:50

标签: c++ multithreading qt

我想要一个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位于主线程中。这好吗?

1 个答案:

答案 0 :(得分:2)

  

然而,writeBytes位于工作线程中,而readBytes位于   主线程。这好吗?

如果您使用的是原始POSIX套接字(例如int文件描述符和BSD套接字API的sendto()调用),那就没关系;但是QUdpSocket派生自QObject,并且QObjects不打算同时被多个线程访问。特别是,快速浏览一下QUdpSocket :: writeDatagram()方法实现,可以看出该方法的作用如底层套接字的延迟初始化,文件描述符的缓存以及信号的发送,其中任何一个都可能与同时进行的交互不良给定正确(错误?)时序的不同线程的非同步访问。您的代码可能会随之而来,但我不相信它能够始终可靠地工作或在所有系统上工作。

我的建议是创建两个QUdpSocket对象,一个用于发送,另一个用于接收。这将确保避免竞争条件,并且额外的QUdpSocket对象不是一个非常大的成本,为安心而付出代价。