QT:无法从另一个线程启用套接字通知程序 [英] QT: socket notifiers cannot be enabled from another thread

查看:364
本文介绍了QT:无法从另一个线程启用套接字通知程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个QTcpSocket,我需要控制它-使用多个线程进行读写.

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

这在QT4中工作正常,但是在QT5中,我收到此错误,似乎只有1个线程可以同时访问套接字.如何使一个套接字可以被多个线程访问?

This works fine in QT4 but in QT5 I am getting this error and it seems that only 1 thread has access to socket at a same time. How do I make it possible for a socket to be accessed by multiple threads?

基本上,我想创建1个用于读取的线程和1个用于写入数据的线程,以便我可以异步读取和处理数据,同时在其余应用程序中执行其他操作.

Basically I want to create 1 thread for reading and 1 thread for writing of data, so that I can asynchronously read and process the data while doing something else in rest of application.

注意:回答 Qt-在新线程中处理QTcpSocket 在这里无济于事,因为它描述了如何将套接字从线程1转移到线程2,然后仅从线程2使用它.我需要在两个线程中都使用它.

Note: answer to Qt - Handle QTcpSocket in a new thread doesn't help here, because it describes how to transfer socket from thread 1 to thread 2 and then use it from thread 2 only. I need to use it from both threads.

推荐答案

您只能从一个线程直接与套接字进行交互(该线程必须运行一个事件循环-因此您应该在其上调用exec()).如果要从另一个线程读/写,则需要使用Signals/Slots.

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.

使用默认连接类型(Qt::AutoConnection)将一个线程上发出的信号连接到另一线程上对象的插槽,将自动确保发生安全的线程传输(使用排队连接).您可以使用Qt::QueuedConection明确地将信号连接到插槽,但是Qt::AutoConnection应该可以正常工作.

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);
};

就像您对问题的评论所说,您需要仔细考虑为什么需要这种行为,您是否真的需要在2个独立的线程上读取套接字接收的相同数据?

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?

这篇关于QT:无法从另一个线程启用套接字通知程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆