Infinite loop and signal deluge
-
My veryLongProcess() performs segmentation on an image.
If it work the result is an image with an overlay, if it fails it returns the original image.
In both cases it will also result a string containing some timers and error codes.The original image comes from a live camera, so the output should be as real-time as possible.
-
So... couldn't you parse the error codes to see if you need to emit, and if so, what?
-
I always need to emit, even if it's an error I will emit the original image, the timers and the error code ...
-
Then, sorry, I don't know how to optimize further. I would say that at most, you'd need to emit a signal every 1/60th of a second (and probably half that or even only every 1/24th of a second), but if you say that you need to draw everything, then I believe you.
I think that if you really need to pass information that fast, that threads may not be the ideal way to do it. It also depends on how much time processing the information at the other end takes. I mean: it doesn't make much sense to send a load of new images to display as a video if the system is still busy with drawing the first image. That will only clog the event queue, which will result in even more delays.
-
I tried to implement Andre's suggestion:
Since I can send many signals I added a int _sentSignals to my class:
@
private:
QMutex canEmitMutex;
int _sentSignals; //!< Safe-guard to avoid signal deluge
bool canEmit() {return _sentSignals<=0;}public:
void signalProcessed();
void signalEmited();// cpp
void ProcessingThread::signalProcessed()
{
canEmitMutex.lock();
_sentSignals--;
canEmitMutex.unlock();
}void ProcessingThread::signalEmited()
{
canEmitMutex.lock();
_sentSignals++;
canEmitMutex.unlock();
}@And now in my processing loop I have
@
while( someCondition )
{
iCanEmit = canEmit();//code
if( iCanEmit )
{
emit someSignal();
signalEmited();
}
//repeat for other signals
}@someSignal is connected to a slot in my main:
@
void MainWindow::slotDisplayStatusMsg(QString text)
{
ui->statusLabel->setText(text);
// Tell processing thread that we processed its signal
if( _procThread ) _procThread->signalProcessed();
}@The problem is that, sometimes, some slot seems to be not executed. Hence _signalSent is not decremented and stays to 1. And my loop stop emiting.
Is it possible that some events are sometimes ignored? -
no, it can't.
but between canEmit and signalEmitted in your while loop, there is a whole, where your raise condition may happen.
So I suggets doing it like this:@
class ProcessingThread
{
private:
QMutex canEmitMutex;
int _sentSignals; //!< Safe-guard to avoid signal deluge
bool canEmit() {return _sentSignals<=0;}
// some more stuffpublic:
// some more stuff
void signalProcessed();
};void ProcessingThread::signalProcessed()
{
QMutexLocker lockObj(&canEmitMutex);
_sentSignals--;
}void ProcessingThread::run()
{
// do some stuff
while( someCondition )
{
// emit lock
{
QMutexLocker lockObj(&canEmitMutex);
if(canEmit())
{
emit someSignal();
_sentSignals++;
}
}
}
// do some stuff
}
@EDIT: corrected code, Gerolf
-
-
perhaps, yes, it was late :-)
-
You could even use a boolean variable, as you only emit once....
-
No in fact I emit more than once, I just simplified my sample code.