Do thread/workers in Qt need a sleep?
-
Hi all,
I have not tested for this yet but I thought I would ask.
In some other languages I've used it seemed like with threads you needed to "sleep" or "yield" so the current thread didn't hog the CPU. Is this the same concept in Qt?
For example in Delphi on a large project I was a part of for all threads we simply made sure in the thread processing that periodically we did a sleep(1). Even though the system could not really do a sleep(1) it was enough to keep the system responsive.
I'm asking this because I am designing a thread/worker set that will be doing some very IO intensive USB comm. It is pretty important that this thread run as quickly as possible and whatever sleeping or yielding that needs to be done needs to be as minimal as possible so the app remains responsive. I might even need to elevate the priority of the thread but not sure about that yet until I can benchmark the USB IO.
So if Qt needs to yield is it best to call the QThread sleep or yield?
Thanks in advance.
-
All ui related code in Qt runs in the main thread. Unless you're doing some very heavy synchronization (which you shouldn't anyway) worker threads have no impact on ui responsiveness.
Whenever you see a sleep (especially a microsleep like you suggested) it's a good sign that your app logic could use tweaking.
Make it snappy. Get in. Do the job. Signal results. Get out.
Yielding makes little sense these days. Schedulers on modern multi-core systems do a good job. No need to try to help them. -
Thanks Chris,
With respect to your make it snappy part:
This IO thread will be running forever (at least while the app is running). So I imagine its loop will be something like this in pseudo code:
while(1) { // Loop through IOs (there will be like 2000 of these) // An IO is just an object that stores a value and a read/write flag ioObject = getNextObject(); if( ioObject->isInput ) // Read the IO over USB and store returned value in the ioObject if( ioObject->isOutput && ioObject.valueChanged ) // Write the new value over USB and clear the value changed flag
}
The ioObjects will be accessed by other threads etc so they will have mutexes in place to protect things. But in general it will be a forever loop that goes through all IOs and either reads them or writes them over the USB port to our custom electronics.
-
You would have to profile of course, but if the locking is not hammered heavily there shouldn't be a problem.
For the sake of presenting another option - you could also go for an event driven system, which is closer to what Qt usually models.
What I mean is you would run an event loop in the worker thread and instead of looping through objects to see if they need some action they would emit a signal to which the worker object would react appropriately. -
Hi Chris,
Well I think for the outputs the signal idea would work just fine. So anytime one of the ioObjects is updated by the app, for output to the hardware, that could generate a signal to the worker.
For the inputs however it is a query response situation. IE the hardware is not going to tell my code that IO XXX updated and here is the value. I have to ask the hardware for the value of XXX. Unfortunately the HW design is mostly complete so making a change to this would be tricky.
What I can do for inputs is to have a priority. There are a ton of inputs I really don't care about so I won't read them very often. There are some that are very important (motor positions, statuses) that I need to read just about every time the loop comes around.
So my example was very basic. There will probably be some priority management in the getNextObject() part of things that figures out what/when it needs to be read.
Good input and thanks again for all your help!