Unsolved QWinEventNotifier: Cannot have more than 62 enabled at one time
-
I have the above error when implementing the below command.
process[k]->start(command);
I am invoking it many more times that 62 times. I am controlling different custom hardware attributes attached to the computer.
I only get this error in windows and not in Linux. Once I addprocess2[k]->waitForFinished();
It works fine but it takes around 2 minutes for it to complete. Whereas in Linux when I don't wait for the processes to finish it returns in 15 seconds or less.
Any thoughts on how I can get the same behaviour in Windows that I have in Linux?
-
Just implement a queue...
private: enum : int { MaxNumOfProcesses = 61 }; QQueue<QPair<QProcess*,command> > processQueue; int processRunning=0; void startProcess(QProcess* proc = nullptr, const QString& command=QString()){ if(proc){ QObject::connect(proc,SIGNAL(finished()),this,SLOT(processReturned())); processQueue.enqueue(QPair(proc,command)); } if(processQueue.isEmpty()) return; if(processRunning>=MaxNumOfProcesses) return; ++processRunning; auto tempProc = processQueue.dequeue(); tempProc.first->start(tempProc.second); } private slots: void processReturned(){ --processRunning; startProcess(); }
-
BTW, the reason for this behavior is explained in QTBUG-8819.
-
@VRonin
Doesn't this code just skip over the process to be executed if proccessrunning is larger than 62 and move on to the next and next until another process is freed? Meaning some process will never get executed? -
@bwcal1999 No, it's just a simple queue. if there are more than 61 processes already running the others will wait until one finishes before starting.
processReturned
is the one who calls
-
Has anyone found a solution for this? I have to ping more than 62 devices with this function and i get the same error. QWinEventNotifier: Cannot have more than 62 enabled at one time
class Pinger : public QObject { Q_OBJECT public: Pinger(QObject *parent = 0) : QObject(parent) { //Have to do this ugliness because QProcess::finished is overloaded auto finishedFunc = static_cast<void(QProcess::*)(int)>(&QProcess::finished); connect(&m_process, finishedFunc, [this](int exitCode) { if( exitCode == 0 ) { emit pingSuccess(); } else { emit pingFailed(); } }); } void run(const QString& hostToPing, int intervalInSeconds, int type, int *deviceFlag) { m_host = hostToPing; QTimer* timer = new QTimer(this); timer->start(intervalInSeconds * 1000); QObject::connect(timer, &QTimer::timeout, [this,type, deviceFlag]() { if (type == 1) { if ( m_process.state() == QProcess::NotRunning ) { m_process.start(QString("ping -w 1 -n 1 " + m_host)); //qDebug() << ""; } else { qDebug() << "Cannot ping, previous ping operation still in progress!"; } } }); } signals: void pingSuccess(); void pingFailed(); private: QProcess m_process; QString m_host; };
-
Hi
You can only have 62 running at the same time.
"WaitForMultipleObjects(Ex) only supports up to MAXIMUM_WAIT_OBJECTS, which is 64"
So as suggested , you must work around it so u only spawn 62 pr time. -
@mardzo said in QWinEventNotifier: Cannot have more than 62 enabled at one time:
Has anyone found a solution for this? I have to ping more than 62 devices with this function and i get the same error. QWinEventNotifier: Cannot have more than 62 enabled at one time
class Pinger : public QObject { Q_OBJECT public: Pinger(QObject *parent = 0) : QObject(parent) { //Have to do this ugliness because QProcess::finished is overloaded auto finishedFunc = static_cast<void(QProcess::*)(int)>(&QProcess::finished); connect(&m_process, finishedFunc, [this](int exitCode) { if( exitCode == 0 ) { emit pingSuccess(); } else { emit pingFailed(); } }); } void run(const QString& hostToPing, int intervalInSeconds, int type, int *deviceFlag) { m_host = hostToPing; QTimer* timer = new QTimer(this); timer->start(intervalInSeconds * 1000); QObject::connect(timer, &QTimer::timeout, [this,type, deviceFlag]() { if (type == 1) { if ( m_process.state() == QProcess::NotRunning ) { m_process.start(QString("ping -w 1 -n 1 " + m_host)); //qDebug() << ""; } else { qDebug() << "Cannot ping, previous ping operation still in progress!"; } } }); } signals: void pingSuccess(); void pingFailed(); private: QProcess m_process; QString m_host; };
Or instead of shelling out to a ping process you could just write a network ping class. Or you could grab a library someone has already written and use that.
Creating 60+ processes isn't a great idea on any OS. Especially for something as simple to code as a ping.
Here's a nice easy to use library with ping support... Poco is a pretty big library though so adding it to your project may not be something you want to do. it is open source so you can always learn how to code a ping properly by viewing their source code. :) This really is a much better way to do what you need instead of spawning tons of processes.