QT: socket notifiers cannot be enabled from another thread

前端 未结 1 1339
死守一世寂寞
死守一世寂寞 2020-12-10 05:53

I have a QTcpSocket and I need to control it - write + read using multiple threads.

This works fine in QT4 but in QT5 I am getting this error and it seems that only

相关标签:
1条回答
  • 2020-12-10 06:48

    You can only directly interact with the socket from one thread (the thread must have an event loop running - so you should have called exec() on it). If you want to read/write from another thread, you will need to use Signals/Slots.

    Connecting a Signal emitted on one thread to a Slot of an object on another thread using the default connection type (Qt::AutoConnection) will automatically ensure a safe thread transfer occurs (using a queued connection). You can explicitly connect a Signal to a Slot using Qt::QueuedConection, but Qt::AutoConnection should work fine.

    // Lives on thread 1
    class MySocketOwner : public QObject
    {
        Q_OBJECT
    
    public:
        MySocketOwner(QObject *Parent = 0)
            : QObject(Parent)
        {
            Socket = new QTcpSocket(this);
            connect(Socket, SIGNAL(readyRead()), this, SLOT(Read()));
        }
    
        ~MySocketOwner()
        {
            delete Socket;
        }
    
    public slots:
        void Read()
        {
            QByteArray Data = Socket->readAll();
            // Do something with the data
        }
    
        void Write(QBytrArray Data)
        {
            // Must always be called on thread 1
            Socket->write(Data);
        }
    
    private:
        QTcpSocket *Socket;
    };
    
    // Lives on thread 2
    class MySocketWriter : public QObject
    {
        Q_OBJECT
    
    public:
        MySocketWriter(QObject *Parent = 0)
            : QObject(Parent)
        {
            // If this is on another thread, connection will be queued
            connect(this, SIGNAL(Write(QByteArray)), MySocketOwnerPointer, SLOT(Write(QBytrArray Data)));
            QByteArray Data;
            // Fill with data
    
            // An event gets put onto thread 1's event queue after this
            emit Write(Data);
        }
    
    signals:
        void Write(QByteArray Data);
    };
    

    Like the comments on your question say, you need to think carefully about why you need this behaviour, do you really need to read the same data received by the socket on 2 separate threads?

    0 讨论(0)
提交回复
热议问题