如何使用相同的可执行文件

时间:2017-06-20 04:13:23

标签: c++ qt multiprocessing

我有一个Worker类的程序,这个类有3 QProcess个。

每个进程都需要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;
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

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

存在不同的解决方案:

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

  • 在单独的帖子中执行Worker::run

  • 致电QCoreApplication::processEvents以处理待处理事件,例如当has_available为假时。

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