我有一个QTcpSocket,我需要控制它 – 使用多个线程写入读取.
这在QT4中工作正常但在QT5中我收到此错误,似乎只有1个线程可以同时访问套接字.如何使多个线程可以访问套接字?
基本上我想创建1个用于读取的线程和1个用于写入数据的线程,这样我就可以在其他应用程序中执行其他操作时异步读取和处理数据.
注意:回答Qt – Handle QTcpSocket in a new thread对此没有帮助,因为它描述了如何将套接字从线程1传输到线程2,然后仅从线程2使用它.我需要从两个线程中使用它.
解决方法
你只能从一个线程直接与套接字交互(线程必须运行一个事件循环 – 所以你应该在它上面调用exec()).如果要从另一个线程读取/写入,则需要使用信号/插槽.
使用默认连接类型(Qt :: AutoConnection)将一个线程上发出的信号连接到另一个线程上的对象的Slot将自动确保发生安全的线程传输(使用排队连接).您可以使用Qt :: QueuedConection显式地将信号连接到插槽,但Qt :: AutoConnection应该可以正常工作.
// 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); };
就像你问题上的评论所说的那样,你需要仔细考虑为什么需要这种行为,你真的需要在两个不同的线程上读取套接字收到的相同数据吗?