无法使用QtNetwork,因为应用程序使用不同的线程
Cannot use QtNetwork because application uses different Threads
当我使用QtNetwork时,我的应用程序中出现了一个奇怪的行为。我可以很容易地创建QTcpSever
和QTcpSocket
实例,一切都运行良好,但当涉及到QTcpSocket::write()
时,会发生以下错误:
错误
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x7f66980022e0), parent's thread is QThread(0x7f66a0020be0), current thread is QThread(0x7f66a0020e20)
QSocketNotifier: Can only be used with threads started with QThread
我觉得奇怪的是:我不知道这个QThread(0x7f66a0020e20)
是什么/在哪里,以及如何对它产生影响(看看下面的调试)
程序
我正在通过网络支持扩展我的主应用程序(它是一个库)。我把网络服务放到了一个额外的班级。
这里是主要应用程序/库的摘录,我的网络支持就是在这里创建的:
QThread *thread = new QThread;
wifi = new WirelessNet(0, thread);
wifi->moveToThread(thread);
connect(thread,SIGNAL(started()), wifi,SLOT(initWifi()));
thread->start();
网络类扩展:
WirelessNet::WirelessNet(QObject *parent, QThread *comThread): QTcpServer(parent)
{
clientThread = comThread;
}
void WirelessNet::initWifi()
{
listen(QHostAddress::Any, 5220);
connect(this,SIGNAL(newConnection()),this,SLOT(connectionRequest()));
}
void WirelessNet::connectionRequest()
{
client = this->nextPendingConnection();
if(client)
connect(client, SIGNAL(readyRead()), this, SLOT(receiveMessage()));
}
void WirelessNet:sendData(QByteArray msg)
{
if (client)
{
qDebug()<<"FIRST "<< client->thread() << " - " << this->thread() << "n";
client->write(msg);
client->waitForBytesWritten();
qDebug()<<"LAST " << client->thread() << " - " << this->thread() << "n";
}
}
(client和clientThread是类成员:分别为QTcpSocket*和QThread*)
调试
以下是控制台在sendData()
部分打印的内容:
FIRST QThread(0x7f66a0020be0) - QThread(0x7f66a0020be0)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x7f66980022e0), parent's thread is QThread(0x7f66a0020be0), current thread is QThread(0x7f66a0020e20)
QSocketNotifier: Can only be used with threads started with QThread
LAST QThread(0x7f66a0020be0) - QThread(0x7f66a0020be0)
结束
换句话说,我不知道应该在哪个对象上应用moveToThread()
。我已经试过client->moveToThread(clientThread)
和this->moveToThread(clientThread)
了。不幸的是,我没有看到任何额外的对象可以检查。
有人有主意吗?
您似乎直接从主线程调用WirelessNet:sendData
。这会导致该函数中的所有内容也在主线程中运行。您的client
存在于新线程中,并且它不是线程安全的。它试图创建子线程,但当前线程与client
所在的线程不同。这就是您收到错误消息的原因。
只需将WirelessNet:sendData
设为插槽并通过来自主线程的信号调用它,就可以修复它。
我的猜测是,类的构造函数在调用线程中被调用,而线程本身在类的run()
方法中运行。解决方案是在run()
方法开始时初始化QTcpServer
,这样初始化和通过该类的通信就可以在同一个线程中完成。
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 通过安装信号处理程序关闭多线程应用程序
- 如何在实时应用程序中锁定线程
- 如何在 MFC 应用程序中启动 ZeroMQ 线程?
- 多线程 gtkmm 应用程序最简单的示例
- 将数组作为多线程应用程序中函数的返回传递
- 修改多线程应用程序中的对象
- 多线程 C++11 应用程序中的同步
- 多线程Windows GUI应用程序中的死锁
- C++多线程应用程序将永远挂起
- 具有多线程应用程序的 Nanomsg 无阻塞双向套接字
- 在 API 和应用程序线程之间共享数据
- 多线程程序线程联接问题
- C++Win32 在低优先级模式下运行应用程序/线程
- 仅在守护程序线程返回后删除它
- 用户模式计划程序线程的最大数量
- GST_DEBUG:如何将日志保存在应用程序内线程的单独文件中
- std::线程实例计数不等于实际应用程序线程计数
- c++程序线程的概念
- CUDA5.0上下文管理,在多GPU环境中使用单个应用程序线程