首页 > 解决方案 > QProcess在启动多次后给出FailedToStart

问题描述

我正在尝试在线程中使用 QProcess 来执行一些操作(读取 I2C 连接)。更新方法每 100 毫秒调用一次:

void TempsReader::update()
{
    if (_currProcess == nullptr) {
        _currProcess = new QProcess();
        connect(_currProcess, &QProcess::errorOccurred, this, &TempsReader::onProcessError);
        connect(_currProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
                this, SLOT(onProcessFinished()));
    }

    _currProcess->start("sh");
    if (_currProcess->waitForStarted()) {
        _currProcess->write("i2cdetect -y 1");
        _currProcess->closeWriteChannel();
        _currProcess->waitForFinished();
    }
}

一段时间后,该过程会出现“FailedToStart”错误并且永远不会再次启动。

在此处输入图像描述

void TempsReader::onProcessError(QProcess::ProcessError error)
{
    qDebug() << error;
    _currProcess->close();
}

void TempsReader::onProcessFinished()
{
    QString devs = _currProcess->readAll();
    _currProcess->waitForFinished();
    // doing some stuff with devs
    _currProcess->close();
}

我该如何解决这个问题?我是否以错误的方式使用 QProcess?以及当它掉入错误槽时如何再次启动该过程。提前致谢。

更新:QProcess::errorString() 给出了这个:“资源错误(fork 失败):打开的文件太多”

在此处输入图像描述

更新:最后我发现了这个问题,它与 QProcess 本身无关。它与 I2C 连接有关。

标签: c++qt5qprocess

解决方案


我的猜测是你失败了,因为你所有的update()调用都共享同一个QProcess对象。

这里发生的是,当您调用 时update(),您将启动该过程。100 毫秒后,您再次调用它而不确保前一个update()已完成等待进程结束。
结果是您尝试启动一个已经启动的进程,因此它失败了。

QProcess对我来说,最简单的解决方案是为每次update()调用创建一个对象。
就像是:

void TempsReader::update()
{
    QProcess * current_process = new QProcess;

    connect(current_process, &QProcess::errorOccured, this, &TempReader::onProcessError);
    connect(current_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &TempReader::onProcessFinished());

    current_process->start("sh"); // Your command
    current_process->waitForStarted();
    current_process->write("i2cdetect -y 1");
    current_process->waitForFinished();

    current_process->deleteLater();
}

或者没有指针:

void TempsReader::update()
{
    QProcess current_process;

    connect(&current_process, &QProcess::errorOccured, this, &TempReader::onProcessError);
    connect(&current_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &TempReader::onProcessFinished());

    current_process.start("sh"); // Your command
    current_process.waitForStarted();
    current_process.write("i2cdetect -y 1");
    current_process.waitForFinished();
}

由于您没有显示代码的调用部分(线程创建,100ms 循环,...),这可能不是您需要的解决方案。
在这种情况下,如果它不能解决您的问题,请告诉我,以便我删除此答案。


推荐阅读