gpt4 book ai didi

c++ - 终止在不同 QThread 中运行的 QProcess

转载 作者:行者123 更新时间:2023-11-28 01:42:07 26 4
gpt4 key购买 nike

我有一个继承QThread 的类,我重新实现了run() 方法。在这个 run 方法中,有一个启动程序的 QProcess(在 run 中声明)。

现在,如果我在该进程仍在运行时关闭我的应用程序,它实际上不会关闭,直到该进程完成。

所以我的问题是如何停止这个过程?

从我在 Qt 文档中读到的内容来看,我不能在这里使用信号/插槽,因为我的进程将与不是主线程的线程具有线程亲和性,因此连接排队,这不会停止我的进程.

我正在使用 Qt 5.8

提前致谢!

编辑:这是线程代码,如果您需要更多,请告诉我

void run()
{
QString cmd;
QProcess p;

connect(&p, SIGNAL(finished(int)), this, SLOT(quit()));
//connect(this, SIGNAL(signalTerminateProcess()), &p, SLOT(kill())); // queued connect that doesn't kill my process

p.start(cmd);
if(p.waitForFinished(-1))
{
qInfo("process done");
}
}

最佳答案

首先,您可以在 QThread 中使用信号和槽,甚至可以使用 Qt::BlockingQueuedConnection 等待槽执行。参见 Qt documentation .

但是,这需要目标 QObject 存在于具有正在运行的事件循环的线程中。在你的例子中,由于你已经重载了 QThread::run(),你将没有事件循环。

在我看来,您有 2 种方法来修复您的代码,要么进行小的修复,要么更改设计并使用事件循环。

1。快速修复

void run()
{
QString cmd;
QProcess p;

connect(&p, SIGNAL(finished(int)), this, SLOT(quit()));
//connect(this, SIGNAL(signalTerminateProcess()), &p, SLOT(kill())); // queued connect that doesn't kill my process

p.start(cmd);
while(! p.waitForFinished(100)) //Wake up every 100ms and check if we must exit
{
if (QThread::currentThread()->isInterruptionRequested())
{
p.terminate();
if (! p.waitForFinished(1000))
p.kill()
break;
}
}
qInfo("process done");
}

int cleanUp()
{
thread->requestInterruption();
thread->wait();
}

QProcess *process = nullptr;
void run()
{
QString cmd;
QProcess p;
process = &p; //You shouldn't do that in real code

connect(&p, SIGNAL(finished(int)), this, SLOT(quit()));
//connect(this, SIGNAL(signalTerminateProcess()), &p, SLOT(kill())); // queued connect that doesn't kill my process

p.start(cmd);
while(! p.waitForFinished(100)) //Wake up every 100ms and check if we must exit
{
QCoreApplication::processEvents();
}
qInfo("process done");
process = nullptr;
}

int cleanUp()
{
QTimer::singleShot(0, process, &QProcess::terminate);
// Qt 5.10 -> QMetaObject::invokeMethod(process, &QProcess::terminate);
if (! thread->wait(1000))
{
QTimer::singleShot(0, process, &QProcess::kill);
thread->wait();
}
}

2。事件循环修复

// Create thread
QThread thread;
thread.start();

// Create process and move it to the other thread
QProcess process;
process.moveToThread(&thread);

void startProcess()
{
p.start(cmd);
}

QMutex mutex;
void stopProcess()
{
p.terminate();
if (!p.waitForFinished(1000))
p.kill();
p.moveToThread(qApp->thread());
mutex.unlock();
}

// Call startProcess() in the other thread
QTimer::singleShot(0, &process, &startProcess);

// Call stopProcess() in the other thread
mutex.lock();
QTimer::singleShot(0, &process, &stopProcess);
mutex.lock();

thread.quit();
if (!thread.wait(100))
thread.terminate();

你可以:

  • 通过使用原子或使用与 Qt::BlockingQueuedConnection 连接的信号替换互斥体。
  • 用槽和 lambda 替换 startProcess()stopProcess()
  • QMetaObject::invokeMethod() 或使用信号替换对 QTimer::singleShot() 的调用。 请注意,您可以将 Qt::BlockingQueuedConnectionQMetaObject::invokeMethod() 一起使用

关于c++ - 终止在不同 QThread 中运行的 QProcess,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46733421/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com