无法使用 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
我觉得奇怪:我不知道what/where这个QThread(0x7f66a0020e20)
是什么以及如何影响它(看看下面调试)
程序
我正在使用网络支持扩展我的主要应用程序(这是一个库)。我把网络服务改成了额外的class。
此处是主要 application/library 的摘录,其中创建了我的网络支持:
QThread *thread = new QThread;
wifi = new WirelessNet(0, thread);
wifi->moveToThread(thread);
connect(thread,SIGNAL(started()), wifi,SLOT(initWifi()));
thread->start();
网络class分机:
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分别是class成员: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)
。不幸的是,我没有看到任何额外的对象来检查。
有没有人有想法?
我的猜测是 class 的构造函数在调用线程中被调用,而线程本身在 class 的 run()
方法中运行。解决方案是在 run()
方法的开头初始化 QTcpServer
,以便通过 class 进行初始化和通信是在同一个线程中完成的。
您似乎是直接从主线程调用 WirelessNet:sendData
。这会导致该函数内的所有内容在主线程中也是 运行 。您的 client
位于新线程中,并且它不是线程安全的。它尝试创建子进程,但当前线程与 client
所在的线程不同。这就是您收到该错误消息的原因。
您可以简单地通过将 WirelessNet:sendData
设为槽并通过来自主线程的信号调用它来修复它。
当我使用 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
我觉得奇怪:我不知道what/where这个QThread(0x7f66a0020e20)
是什么以及如何影响它(看看下面调试)
程序
我正在使用网络支持扩展我的主要应用程序(这是一个库)。我把网络服务改成了额外的class。
此处是主要 application/library 的摘录,其中创建了我的网络支持:
QThread *thread = new QThread;
wifi = new WirelessNet(0, thread);
wifi->moveToThread(thread);
connect(thread,SIGNAL(started()), wifi,SLOT(initWifi()));
thread->start();
网络class分机:
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分别是class成员: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)
。不幸的是,我没有看到任何额外的对象来检查。
有没有人有想法?
我的猜测是 class 的构造函数在调用线程中被调用,而线程本身在 class 的 run()
方法中运行。解决方案是在 run()
方法的开头初始化 QTcpServer
,以便通过 class 进行初始化和通信是在同一个线程中完成的。
您似乎是直接从主线程调用 WirelessNet:sendData
。这会导致该函数内的所有内容在主线程中也是 运行 。您的 client
位于新线程中,并且它不是线程安全的。它尝试创建子进程,但当前线程与 client
所在的线程不同。这就是您收到该错误消息的原因。
您可以简单地通过将 WirelessNet:sendData
设为槽并通过来自主线程的信号调用它来修复它。