QProcess in thread 工作,但有两种类型的输出错误



我正在学习QT多线程。 使用以下代码,它可以正常工作,但是有两个类型错误 代码太简单了,无法找出出了什么问题。

CmdController(Controller thread( -> CMD(Ping test thread( -> QProcess(excute "ping"(

主.c

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// create Test object, and then execute “ping” cmd under windows
CmdController Test;
Test.process();
return a.exec();
}

CmdController.h

// deal with "ping" command
class Cmd : public QObject
{
Q_OBJECT
public:
explicit Cmd();
private:
QProcess CmdExe;
public slots:
void process();
void readFromStdOut();
};

// Controller class
class CmdController : public QObject
{
Q_OBJECT
public:
explicit CmdController();
~CmdController();
signals:
void process();
private:
QThread mThread;
Cmd mCmd;
};

CmdController.c

Cmd::Cmd()
{
connect(&CmdExe, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdOut()));
}
void Cmd::process()
{
CmdExe.start("ping", {"www.baidu.com"});
}

void Cmd::readFromStdOut()
{
QByteArray resault = CmdExe.readAllStandardOutput();
qDebug() << QTextCodec::codecForName("GBK")->toUnicode(resault);
}
CmdController::CmdController()
{
mCmd.moveToThread(&mThread);
connect(this, &CmdController::process, &mCmd, &Cmd::process);
mThread.start();
}
CmdController::~CmdController()
{
mThread.exit();
mThread.wait();
}

输出:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QProcess(0x6ffdf0), parent's thread is QThread(0x1f6510), current thread is QThread(0x6ffdd0)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QProcess(0x6ffdf0), parent's thread is QThread(0x1f6510), current thread is QThread(0x6ffdd0)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QProcess(0x6ffdf0), parent's thread is QThread(0x1f6510), current thread is QThread(0x6ffdd0)
"rn正在 Ping www.a.shifen.com [180.101.49.42] 具有 32 字节的数据:rn"
"来自 180.101.49.42 的回复: 字节=32 时间=31ms TTL=53rn"
"来自 180.101.49.42 的回复: 字节=32 时间=31ms TTL=53rn"
"来自 180.101.49.42 的回复: 字节=32 时间=30ms TTL=53rn"
"来自 180.101.49.42 的回复: 字节=32 时间=30ms TTL=53rnrn180.101.49.42 的 Ping 统计信息:rn    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),rn往返行程的估计时间(以毫秒为单位):rn    最短 = 30ms,最长 = 31ms,平均 = 30msrn"
QObject::connect: Cannot queue arguments of type 'HANDLE'
(Make sure 'HANDLE' is registered using qRegisterMetaType().)

错误 1st: 1-6行输出错误,显示创建子对象失败,三倍。 ping 测试正常。 那么,谁导致了错误?

QThread(0x6ffdd0( 是 Cmd-object, QThread(0x1f6510( 是 CmdController-object, QProcess(0x6ffdf0(显然是QProcess-object, 这是否意味着QProcess,尝试创造一些东西?

错误 2ed: 最后两行。 谷歌搜索,找不到"句柄"它是什么。

如果从中删除多线程内容 CmdController(Controller thread( -> CMD(Ping test thread( -> QProcess(excute "ping"( 自 CmdController(Controller thread( -> QProcess(excute "ping"( 不会有错误,一切正常。

我很困惑。

谢谢。

要理解这个问题,首先必须清楚 QObject 只能在它所属的线程中执行,如果执行另一个线程,那么 Qt 不保证它有效,这就是在这种情况下发生的事情。

让我们分析一下每个 QObject 属于哪个线程,默认情况下 QObject 属于创建它的线程或它父线程的线程,所以当你创建对象"Test"时,它属于主线程,开头的对象"mCmd"属于主线程,然后你把它移动到"mThread", "CmdExe"属于创建它的线程,也就是说,属于主线程,但"Cmd"进程方法在辅助线程中执行,但"CmdExe"在导致问题的主线程中执行。

解决方案是使"CmdExe"成为"Cmd"的儿子,以便两者属于同一线程并且不会产生问题。

// ...
class Cmd : public QObject
{
Q_OBJECT
public:
explicit Cmd(QObject *parent=nullptr);
private:
QProcess *CmdExe;
public slots:
void process();
void readFromStdOut();
};
// ...

// ...
Cmd::Cmd(QObject *parent):QObject(parent),CmdExe(new QProcess(this))
{
connect(CmdExe, &QProcess::readyReadStandardOutput, this, &Cmd::readFromStdOut);
}
void Cmd::process()
{
CmdExe->start("ping", {"www.baidu.com"});
}
// ...

最新更新