QProcess在启动多次后给出FailedToStart

Posted

技术标签:

【中文标题】QProcess在启动多次后给出FailedToStart【英文标题】:QProcess give FailedToStart after starting multiple times 【发布时间】:2019-12-18 12:59:13 【问题描述】:

我正在尝试在线程中使用 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 连接有关。

【问题讨论】:

QProcess::errorString() 说什么? 可能会出现几个问题。首先,尝试使用readAllStandardErrorreadAllStandardOutput 获取进程的输出,以查看命令(i2cdetect)是否返回一些错误。另外,获取进程的state 以查看它是否完成,如果没有,您可能需要terminatekill 进程。而且,你可能需要在结束后delete _currProcess; 我认为失败是因为您的update() 函数被多次调用但在同一个QProcess 上工作。如果你打电话给update(),你就开始这个过程,很好。但是,如果您再次调用update() 而没有确保之前的update() 已经完成(仍在等待进程结束),您将尝试启动一个已经启动的进程(因为您使用相同的QProcess 对象),因此启动会失败。 @acraig5075 好点! : "资源错误(fork 失败):打开的文件太多" @user1810087 readAllStandardError/Output 什么也没给出! 【参考方案1】:

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

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

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

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();


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

【讨论】:

感谢您分享您的想法。我已经测试过这个解决方案但没有帮助:(但请不要删除它。也许我会提供类似的解决方案并更新你。【参考方案2】:

最后我发现了这个问题,它与 QProcess 本身无关。它与 I2C 连接有关。我在更新中使用了这个命令:wiringPiI2CSetup(addr);并且每次都会打开一个新设备。

【讨论】:

以上是关于QProcess在启动多次后给出FailedToStart的主要内容,如果未能解决你的问题,请参考以下文章

如何读取 QProcess 输出

QProcess与外部程序的调用(可以通过设置管道来交互)

如果程序完成,QProcess exe 不会关闭

QProcess 没有启动

如何在 QProcess 中使用队列?

QProcess 无法启动进程:未找到进程