PDA

View Full Version : QTimer and main eventLoop is there possible race condition?



franki
5th July 2012, 10:55
Hi all,

I'm not sure if such a situation creates race conditions and thus, should I take care about it?
I have QTimer which invokes some action periodically, every 100ms, this action can sometime take more than 100ms to complete, and also during this action I can stop QTimer (like timer->stop() ) - so in that case, when timer will be stoped during this, lets say 150ms, to complete my task, and after this eventLoop will start, will it produce event saying QTimer timeout, or not?

best regards
Marek

high_flyer
5th July 2012, 11:18
Race condition is something else, not what you describe.
In general, if you have a closed loop (I mean without calling processEvents() in it) then while the loop runs no signal slots will be processes, thus if you stop your timer over a slot connection, it wont be evoked before your loop ends.
If you want to be able to stop your timer before your loop ends, you will have to call processEvents() in it.

franki
5th July 2012, 11:53
Thanks,

So in other words, QTimer object does not generate event (timeout) to main event loop by itself, and only during processing of main event loop, active QTimer's are checked if any of them reached timeout, and then event is generated, right ?

Marek

high_flyer
5th July 2012, 13:04
No.
QTimer DOES generate an event to the main loop, and the main loop has to process it - but if the main loop does not get CPU time to process it, it doesn't get processed. This situation occurs in busy loops inside the main event loop (your main application thread).
So if you have a slot running a busy loop in the main thread, you have to call processEvents() to give the main loop chance to process any pending events - or use threads.
However when you are looking at response resolution of few ms, you will have to live with a timing margin in both solutions.

wysota
5th July 2012, 13:26
Actually it depends what you mean. Timers as such do not generate events but are rather checked as part of the event loop whether they reached their timeout. If so, then the application will generate a timer event for the object interested in the timer's timeout (be it the timer object itself or the QObject instance calling startTimer() or using QBasicTimer).

So to sum things up, this will execute the slot only once:


QTimer t;
connect(&t, SIGNAL(timeout()), ..., ...);
t.start(1000); // 1s
sleep(100); // 100s
qApp->processEvents();// lets the timeout be checked and generates an event for the 't' object that will eventually call the slot from line #2

high_flyer
5th July 2012, 13:33
So to sum things up, this will execute the slot only once:
after 100s.

franki
5th July 2012, 13:51
So what I'm really asking is:
if we put line:


t.stop()

after line #4 and before line #5 - will there be any timeout event in main loop waiting to be processed, or there won't be any event because it is generated on the fly when main loop is processed.

Thanks
Marek

d_stranz
5th July 2012, 19:14
Come on, it's a 5-line program. It is taking you longer to write these posts than it would to simply type in those 5 lines and try it yourself. Once you've done that, you can report your results here.

franki
5th July 2012, 20:13
You right ;)

timeout event is not generated in that case. I did it in separate thread, but probably it doesn't matter.

Marek

wysota
5th July 2012, 22:16
So what I'm really asking is:
if we put line:

after line #4 and before line #5 - will there be any timeout event in main loop waiting to be processed, or there won't be any event because it is generated on the fly when main loop is processed.

It's just an academic discussion. The timer can timeout at any point in time close to what the timer is set for depending on many aspects you have little control over. You should always assume the timer fires if it was meant to fire. In your example if you call stop() as part of another timer's timer event (or slot) then whether this timer fires depends on whether it is earlier in the timer list than the timer you're currently processing. You should never expect to stop a timer that is intended to fire NOW. Then you won't have to ask yourself such questions.

BTW. Regarding your last statement -- using threads might matter.