Qt 运行多组QProcess';接二连三
我需要调用外部程序Qt 运行多组QProcess';接二连三,qt,asynchronous,polling,qprocess,Qt,Asynchronous,Polling,Qprocess,我需要调用外部程序N多次。我想同时做这件事。因此,到目前为止,我的策略是启动Nq进程,并对已启动和已完成的进程进行计数。(这样我就能知道他们什么时候都完成了) 但是,外部程序占用了相当多的RAM,因此我不希望在任何时候有更多的4个并行进程 这方面的好策略是什么 我认为信号/插槽不足以实现这一点(我想不出一种不太复杂的方法)…也许我可以用队列做些什么 如何确保一次只运行4个进程? 然后,我如何确定所有N进程最终何时完成 (PySt/Pyqt的答案优先,但C++是OK)< /P> < P>概念证明:
N
多次。我想同时做这件事。因此,到目前为止,我的策略是启动N
q进程,并对已启动和已完成的进程进行计数。(这样我就能知道他们什么时候都完成了)
但是,外部程序占用了相当多的RAM,因此我不希望在任何时候有更多的4个并行进程
这方面的好策略是什么
我认为信号/插槽不足以实现这一点(我想不出一种不太复杂的方法)…也许我可以用队列做些什么
如何确保一次只运行4个进程?
然后,我如何确定所有N
进程最终何时完成
(PySt/Pyqt的答案优先,但C++是OK)< /P> < P>概念证明:
h文件#ifndef CPROCESSRUNNER_H
#define CPROCESSRUNNER_H
#include <QObject>
#include <QQueue>
class QProcess;
class CProcessRunner : public QObject
{
Q_OBJECT
Q_PROPERTY(int processCount READ processCount WRITE setProcessCount)
public:
explicit CProcessRunner(QObject *parent = 0);
~CProcessRunner();
void addProcess(const QString& program);
int processCount() const;
public slots:
void setProcessCount(int arg);
private slots:
void startFreeProcesses();
private:
int getActiveProcessCount() const;
QQueue<QProcess*> m_processes;
int m_processCount;
};
#endif // CPROCESSRUNNER_H
\ifndef CPROCESSRUNNER\u H
#定义CPROCESSRUNNER\u H
#包括
#包括
类QProcess;
CProcessRunner类:公共QObject
{
Q_对象
Q_属性(int processCount READ processCount WRITE setProcessCount)
公众:
显式CProcessRunner(QObject*parent=0);
~cprocesrunner();
无效添加过程(常量字符串和程序);
int processCount()常量;
公众时段:
void setProcessCount(int arg);
专用插槽:
void startfreeprocesss();
私人:
int getActiveProcessCount()常量;
qm_过程;
int m_进程计数;
};
#endif//CPROCESSRUNNER\u H
cpp文件
#include "CProcessRunner.h"
#include <QProcess>
CProcessRunner::CProcessRunner(QObject *parent)
: QObject(parent)
, m_processCount(0)
{
}
CProcessRunner::~CProcessRunner()
{
}
void CProcessRunner::addProcess(const QString& program)
{
QProcess* pProcess = new QProcess(this);
pProcess->setObjectName(program);
m_processes.enqueue(pProcess);
startFreeProcesses();
}
int CProcessRunner::processCount() const
{
return m_processCount;
}
void CProcessRunner::setProcessCount(int arg)
{
m_processCount = arg;
}
void CProcessRunner::startFreeProcesses()
{
while (!m_processes.isEmpty() && (getActiveProcessCount() < m_processCount)) {
QProcess* pProcess = m_processes.dequeue();
connect(pProcess, SIGNAL(finished(int)), this, SLOT(startFreeProcesses()));
connect(pProcess, SIGNAL(finished(int)), pProcess, SLOT(deleteLater()));
pProcess->start(pProcess->objectName());
pProcess->waitForStarted(-1);
}
}
int CProcessRunner::getActiveProcessCount() const
{
int result = 0;
foreach (QProcess* pProcess, findChildren<QProcess*>()) {
if (pProcess->state() == QProcess::Running) {
result++;
}
}
return result;
}
#包括“cprocesrunner.h”
#包括
CProcessRunner::CProcessRunner(QObject*父对象)
:QObject(父对象)
,m_processCount(0)
{
}
CProcessRunner::~CProcessRunner()
{
}
void CProcessRunner::addProcess(常量QString和程序)
{
QProcess*pProcess=新的QProcess(此);
p进程->设置对象名称(程序);
m_进程排队(pProcess);
startfreeprocesss();
}
int CProcessRunner::processCount()常量
{
返回m_processCount;
}
void CProcessRunner::setProcessCount(int arg)
{
m_processCount=arg;
}
void CProcessRunner::startfreeprocesss()
{
而(!m_processs.isEmpty()&&(getActiveProcessCount()start(pProcess->objectName());
p进程->等待开始(-1);
}
}
int CProcessRunner::getActiveProcessCount()常量
{
int结果=0;
foreach(QProcess*ppprocess,findChildren()){
如果(pProcess->state()==QProcess::Running){
结果++;
}
}
返回结果;
}
以下是我当前使用Pyside的实现,仅供参考。
我希望能够捕获每个进程的输出并将其传递(用于显示在QTextEdit
或类似文件中)。为此,我为每个进程分配了一个编号,并将它的stdout和stderr连接到插槽,然后插槽将发出消息和进程位置。
我不相信我目前对该功能的实现,但下面是:
class ProcessRunner(QtCore.QObject):
'''
Runs N processes in groups of M
'''
singleProcessFinished = QtCore.Signal()
error = QtCore.Signal(tuple) #(process number, message)
message = QtCore.Signal(tuple) #(process number, message)
def __init__(self, maxProcesses=4, parent=None):
super(ProcessRunner, self).__init__(parent)
self.processQueue = Queue.Queue()
self.maxProcesses = maxProcesses
self.activeProcessCount = 0
self._processNumber = 0
def addProcess(self, program, args):
'''
Add a process to the process queue
Args:
program (str): String of program path and arguments, separated by one or more spaces
'''
self._processNumber += 1
if self._processNumber == self.maxProcesses:
self._processNumber = 0
proc = QtCore.QProcess(self)
proc.readyReadStandardError.connect(lambda pos=self._processNumber, process=proc: self.emit_error(pos, proc))
proc.readyReadStandardOutput.connect(lambda pos=self._processNumber, process=proc: self.emit_output(pos, proc))
self.processQueue.put((proc, program, args))
self.startFreeProcesses()
def startFreeProcesses(self):
'''
Starts all waiting processes up to a maximum of self.maxProcesses
'''
while (not self.processQueue.empty()) and (self.activeProcessCount < self.maxProcesses):
proc, program, args = self.processQueue.get()
proc.finished.connect(self.startFreeProcesses)
proc.finished.connect(proc.deleteLater)
proc.finished.connect(self.singleProcessFinished.emit)
proc.finished.connect(self._decreaseActiveProcessCount)
proc.start(program, args)
proc.waitForStarted(-1)
self._increaseActiveProcessCount()
def _decreaseActiveProcessCount(self):
self.activeProcessCount -= 1
def _increaseActiveProcessCount(self):
self.activeProcessCount += 1
def emit_error(self, pos, proc):
self.error.emit(pos, str(proc.readAllStandardError()))
def emit_error(self, pos, proc):
self.error.emit(pos, str(proc.readAllStandardOutput()))
类ProcessRunner(QtCore.QObject):
'''
以M为一组运行N个进程
'''
singleProcessFinished=QtCore.Signal()
错误=QtCore.Signal(元组)#(进程号,消息)
message=QtCore.Signal(元组)#(进程号,消息)
def uuu init uuuu(self,maxprocess=4,parent=None):
超级(ProcessRunner,self)。\uuuuu初始化\uuuuuu(父级)
self.processQueue=Queue.Queue()
self.maxprocess=maxprocess
self.activeProcessCount=0
self.\u processNumber=0
def addProcess(自身、程序、参数):
'''
将进程添加到进程队列
Args:
程序(str):程序路径和参数的字符串,由一个或多个空格分隔
'''
self.\u processNumber+=1
如果self.\u processNumber==self.maxprocess:
self.\u processNumber=0
proc=QtCore.QProcess(self)
proc.readyReadStandardError.connect(lambda pos=self.\u processNumber,process=proc:self.emit\u error(pos,proc))
proc.readyReadStandardOutput.connect(lambda pos=self.\u processNumber,process=proc:self.emit\u output(pos,proc))
self.processQueue.put((进程、程序、参数))
self.startfreeprocesss()
def STARTFREEPROCESS(自):
'''
启动所有等待进程,最多可启动self.maxprocess
'''
而(不是self.processQueue.empty())和(self.activeProcessCount的内容,
…这样最好吗?您可以签入startFreeProcesss是getActiveProcessCount等于零。完成后,您将检查每个进程是否已完成所有进程。m_processCount
应重命名为m_maxAsyncProcessCount
,或类似名称。除此之外,看起来很棒,而且完成了任务!你的答案不加修改是行不通的。StartFreeProcesss()中的循环永远无法运行,因为m_processCount从未递增。我添加了行setProcessCount(processCount()+1);正在进行中。然后在startFreeProcess中,decr