gpt4 book ai didi

c++ - 如何使用相同的可执行文件在后台运行 3 QProcess

转载 作者:行者123 更新时间:2023-11-28 01:47:03 25 4
gpt4 key购买 nike

我有一个程序,它有一个 Worker 类,这个类有 3 个 QProcesses。

每个进程都需要一个 QDate 作为参数。我想在后台运行所有这些。

问题

如果我尝试指定超过 3 个日期(意味着所有进程都在运行),整个程序卡住。

我已经尝试使用 QProcess::startDetached 但它会弹出我不喜欢的命令提示符。

我希望一切都在后台运行,3 个进程同时运行。

这是我的代码:

worker.h

#ifndef WORKER_H
#define WORKER_H

#include <QObject>

#include <QDate>
#include <QProcess>
#include <QQueue>

class Worker: public QObject
{
Q_OBJECT

signals:
void processed(QString& date);
void error(QString& error);
void done(QString& done);

public:
Worker();

void run(QDate& start, QDate& end, int delay);

private slots:

void onFinished1(int exitCode, QProcess::ExitStatus exitStatus);
void onError1(QProcess::ProcessError);

void onFinished2(int exitCode, QProcess::ExitStatus exitStatus);
void onError2(QProcess::ProcessError);

void onFinished3(int exitCode, QProcess::ExitStatus exitStatus);
void onError3(QProcess::ProcessError);

private:
QProcess* worker1;
QProcess* worker2;
QProcess* worker3;

QQueue<QDate> date_list;
int running;
};

#endif // WORKER_H

worker.cpp

#include "worker.h"

#include <QDebug>
#include <QStringList>

Worker::Worker()
{
worker1 = new QProcess(this);
worker2 = new QProcess(this);
worker3 = new QProcess(this);

connect(worker1, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(onFinished1(int,QProcess::ExitStatus)));
connect(worker1, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(onError1(QProcess::ProcessError)));

connect(worker2, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(onFinished2(int,QProcess::ExitStatus)));
connect(worker2, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(onError2(QProcess::ProcessError)));

connect(worker3, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(onFinished3(int,QProcess::ExitStatus)));
connect(worker3, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(onError3(QProcess::ProcessError)));

running = 0;
}

void
Worker::onFinished1(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug() << "worker 1: "
<< "Exit Code: " << exitCode
<< "Exit Status: " << exitStatus;

running -= 1;
if (date_list.empty() && running == 0) {
//system("rm output.xlsx");
system("copy .\\extractor\\output.xlsx output.xlsx");
emit done(QString("Done generating output.xlsx"));
}
}

void
Worker::onFinished2(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug() << "worker 2: "
<< "Exit Code: " << exitCode
<< "Exit Status: " << exitStatus;

running -= 1;
if (date_list.empty() && running == 0) {
//system("rm output.xlsx");
system("copy .\\extractor\\output.xlsx output.xlsx");
emit done(QString("Done generating output.xlsx"));
}
}

void
Worker::onFinished3(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug() << "worker 3: "
<< "Exit Code: " << exitCode
<< "Exit Status: " << exitStatus;

running -= 1;
if (date_list.empty() && running == 0) {
//system("rm output.xlsx");
system("copy .\\extractor\\output.xlsx output.xlsx");
emit done(QString("Done generating output.xlsx"));
}
}

void
Worker::onError1(QProcess::ProcessError /* error */)
{
qDebug() << "worker 1: "
<< "Error: " << worker1->errorString();

running -= 1;
emit error(worker1->errorString());
}

void
Worker::onError2(QProcess::ProcessError /* error */)
{
qDebug() << "worker 2: "
<< "Error: " << worker2->errorString();

running -= 1;
emit error(worker2->errorString());
}

void
Worker::onError3(QProcess::ProcessError /* error */)
{
qDebug() << "worker 3: "
<< "Error: " << worker3->errorString();

running -= 1;
emit error(worker3->errorString());
}

void
Worker::run(QDate& start, QDate& end, int delay)
{
qDebug() << __FUNCTION__
<< start
<< end
<< delay;

while(start <= end) {
date_list.push_back(start);
start = start.addDays(1);
}

QProcess * current;
QDate processed_date;
QStringList args;

qDebug() << date_list;

while(! date_list.empty()) {
bool has_available = false;
if (worker1->state() != QProcess::Running) {
current = worker1;
processed_date = date_list.dequeue();
has_available = true;
} else if (worker2->state() != QProcess::Running) {
current = worker2;
processed_date = date_list.dequeue();
has_available = true;
} else if (worker3->state() != QProcess::Running) {
current = worker3;
processed_date = date_list.dequeue();
has_available = true;
}

// Has available worker, start worker
if (has_available) {
running += 1;

QString sdate = processed_date.toString("yyyy-MM-dd");
args << sdate << QString::number(delay);
current->start(".\\release\\extractor\\content.exe", args);
args.clear();
emit processed(sdate);
}
qDebug() << "running: " << running;
}
}

有什么想法吗?

最佳答案

您的程序卡住是因为它一直忙于等待 QProcess 完成,即 while(1)。因此,在处理完所有日期之前,您不会返回到主事件循环。如果您等待的时间足够长,您的程序将解冻。

存在不同的解决方案:

  • 使用 finished 事件开始处理新日期(直到列表为空),即删除无限/等待循环 while(1)

  • 在单独的线程中执行 Worker::run

  • 调用QCoreApplication::processEvents处理未决事件,例如当 has_available 为 false 时。

请注意,我更喜欢第一种解决方案,因为 Qt 是一个事件驱动系统。

关于c++ - 如何使用相同的可执行文件在后台运行 3 QProcess,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44643701/

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