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()
说什么?
可能会出现几个问题。首先,尝试使用readAllStandardError
和readAllStandardOutput
获取进程的输出,以查看命令(i2cdetect)是否返回一些错误。另外,获取进程的state
以查看它是否完成,如果没有,您可能需要terminate
或kill
进程。而且,你可能需要在结束后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(¤t_process, &QProcess::errorOccured, this, &TempReader::onProcessError);
connect(¤t_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的主要内容,如果未能解决你的问题,请参考以下文章