MultiThreading problem in QT Application.
I have a multiThreaded application the main UI Thread and the worker
Thread. I have set the UI Thread with TimeCriticalPriority and the
worker thread with the Normal Priority. So that my UI does not freeze
at any point of time.
But when i try to animate a screen for switching from one screen to
other screen I see jerks on the UI.
The problem here is, when the UI Thread is animating to switch the
screens, the platform switches from UI Thread to the Worker thread
resulting in jerks. How can i solve this issue ?
I suppose the following solutions might help me to resolve these
issues. But how do i implement the solution ?
1. Making the worker thread wait untill the animation in UI thread is finished.
- how should i make the worker thread wait ?
2. Making the UI thread busy untill the animation gets over ?
- how can i make the UI thread busy ? (possible work around
solution might be calling some recursive functions in UI Thread so it does
not switch to worker thread).
Is there any other way to switch the screens from left to right or
vise versa without usingQPropertyAnimation in QT?
Any suggestion/help on this is highly appriciated.
Can anyone please let me know the possible solutions for this ?
Thanks in advance.
Best Regards
Varun Jajee
Instead of raising the priority of your UI thread, you might want to lower the priority of your worker thread(s) (e.g. to LowPriority or LowestPriority). That way your worker threads won't take CPU cycles from away from other threads/processes that your program might be indirectly relying on (e.g. threads that the OS uses to track the mouse, or similar). (it's also preferable to lower thread priorities than to raise them, since some OS's prevent non-root processes/threads from raising their priority)
Also you might want to see if there are any Mutexes that your UI thread locks that might also be locked by the worker thread. If there are, these might be causing a priority inversion that results in your UI thread being blocked until the worker thread releases the mutex.
Related
I'm working on a simulation model that iterates over time steps. At times when the model results start to go South, I want to be able to click on a button to halt the iteration. However, if my testing is correct, when the iteration is running in the UI thread, the Button.Click event is not actuated because the thread is busy iterating. Is that correct? Is there a way to interrupt the UI thread with a button click when the thread is really busy?
One way to handle this problem is to create a Task using the Task Parallel Library to do the computationally-heavy iterations. I'm starting to work on this approach in case there is no way to interrupt the UI thread but I thought I'd check here to make sure I'm not missing a simpler approach.
The problem with your idea to interrupt your calculations on the UI thread is that it requires the cooperation of the UI thread, which is already slammed doing your calculating. For the UI thread to be able to process your button click the calculating needs to stop so the thread can go back to processing UI events. That means saving your progress so you can pick up where you left off later.
This kind of pausing and resuming seems likely to be more trouble than spinning the computation off into its own thread, it is not totally undo-able (the Netscape browser that JWZ developed worked like this, in a single thread), but the reason the multithreaded approach is encouraged is because it's the way that requires the least work, and keeps your calculation code the most focused on the domain and the least chopped up.
If you put the computation in its own thread then the UI thread will be responsive, the OS will make sure both threads get to run. You can make the calculation check for interruption periodically, you can have a progress bar with a cancel button, and you won't have to worry about stopping work to process UI events.
I'm assuming a UI where you have a single event dispatch thread that is responsible for handling UI events. This is how Swing works in Java and it's a popular choice for lots of GUI toolkits because multithreaded solutions are susceptible to deadlocks (events coming from the user will acquire locks in a different order than events coming from the back end). You can specify tags for language and platform to get more relevant answers.
My app has been drawing its graphics from a worker thread for over 10 years now and I've never had any problems with it. The worker thread draws to my HWND (created by the main thread) like this:
hdc = GetDC(hwnd);
SetDIBitsToDevice() ... or StretchDIBits()
ReleaseDC(hwnd, hdc);
After having ported my app to other platforms, I began to realize that drawing from any other thread than the main thread is usually a no-go on many platforms (e.g. macOS). My research has shown that this might be true for Win32 as well but I'm still lacking a definite answer.
Thus, my question:
Is it allowed to draw to my window like shown above from a worker thread that did not create the window it is drawing to? Note that the worker thread is really the only thread that draws to the window. The main thread doesn't do any drawing. Not even in WM_PAINT. Drawing in WM_PAINT is unnecessary in my case because the worker thread draws at 50fps.
If it isn't allowed, what's the best way to delegate drawing from the worker thread to the main thread?
Is it allowed to draw to my window like shown above from a worker thread that did not create the window it is drawing to?
It may not be the best solution to your problem, but it's safe, as long as you respect the documented rules for GetDC:
Note that the handle to the DC can only be used by a single thread at any one time.
ReleaseDC must be called from the same thread that called GetDC.
If you do render to the same device context from multiple threads, you are responsible for synchronizing accesses to it.*
As explained in the comments, a better solution would be to generate the DIB from the worker thread, and have this thread update the window by calling RedrawWindow. The main thread can then StretchBlt in its WM_PAINT handler. Calling RedrawWindow across threads implements a synchronization barrier. When the call returns, rendering on the target thread has run to completion, and it's safe to re-use the DIB.
* See Thread affinity of user interface objects, part 2: Device contexts.
How do you tell the thread scheduler in linux to not interrupt your thread for any reason? I am programming in user mode. Does simply locking a mutex acomplish this? I want to prevent other threads in my process from being scheduled when a certain function is executing. They would block and I would be wasting cpu cycles with context switches. I want any thread executing the function to be able to finish executing without interruption even if the threads' timeslice is exceeded.
How do you tell the thread scheduler in linux to not interrupt your thread for any reason?
Can't really be done, you need a real time system for that. The closes thing you'll get with linux is to
set the scheduling policy to a realtime scheduler, e.g. SCHED_FIFO, and also set the PTHREAD_EXPLICIT_SCHED attribute. See e.g. here , even now though, e.g. irq handlers and other other stuff will interrupt your thread and run.
However, if you only care about the threads in your own process not being able to do anything, then yes, having them block on a mutex your running thread holds is sufficient.
The hard part is to coordinate all the other threads to grab that mutex whenever your thread needs to do its thing.
You should architect your sw so you're not dependent on the scheduler doing the "right" thing from your app's point of view. The scheduler is complicated. It will do what it thinks is best.
Context switches are cheap. You say
I would be wasting cpu cycles with context switches.
but you should not look at it that way. Use the multi-threaded machinery of mutexes and blocked / waiting processes. The machinery is there for you to use...
You can't. If you could what would prevent your thread from never releasing the request and starving other threads.
The best you can do is set your threads priority so that the scheduler will prefer it over lower priority threads.
Why not simply let the competing threads block, then the scheduler will have nothing left to schedule but your living thread? Why complicate the design second guessing the scheduler?
Look into real time scheduling under Linux. I've never done it, but if you indeed do NEED this this is as close as you can get in user application code.
What you seem to be scared of isn't really that big of a deal though. You can't stop the kernel from interrupting your programs for real interrupts or of a higher priority task wants to run, but with regular scheduling the kernel does uses it's own computed priority value which pretty much handles most of what you are worried about. If thread A is holding resource X exclusively (X could be a lock) and thread B is waiting on resource X to become available then A's effective priority will be at least as high as B's priority. It also takes into account if a process is using up lots of cpu or if it is spending lots of time sleeping to compute the priority. Of course, the nice value goes in there too.
How do I control the number of threads that my program is working on?
I have a program that is now ready for mutithreading but one problem is that the program is extremely memory intensive and i have to limit the number of threads running so that i don't run out of ram. The main program goes through and creates a whole bunch of handles and associated threads in suspended state.
I want the program to activate a set number of threads and when one thread finishes, it will automatically unsuspended the next thread in line until all the work has been completed. How do i do this?
Someone has once mentioned something about using a thread handler, but I can't seem to find any information about how to write one or exactly how it would work.
If anyone can help, it would be greatly appreciated.
Using windows and visual c++.
Note: i don't need to worry about the traditional problems of access with the threads, each one is completely independent of each other, its more of like batch processing rather than true mutithreading of a program.
Thanks,
-Faken
Don't create threads explicitly. Create a thread pool, see Thread Pools and queue up your work using QueueUserWorkItem. The thread pool size should be determined by the number of hardware threads available (number of cores and ratio of hyperthreading) and the ratio of CPU vs. IO your work items do. By controlling the size of the thread pool you control the number of maximum concurrent threads.
A Suspended thread doesn't use CPU resources, but it still consumes memory, so you really shouldn't be creating more threads than you want to run simultaneously.
It is better to have only as many threads as your maximum number of simultaneous tasks, and to use a queue to pass units of work to the pool of worker threads.
You can give work to the standard pool of threads created by Windows using the Windows Thread Pool API.
Be aware that you will share these threads and the queue used to submit work to them with all of the code in your process. If, for some reason, you don't want to share your worker threads with other code in your process, then you can create a FIFO queue, create as many threads as you want to run simultaneously and have each of them pull work items out of the queue. If the queue is empty they will block until work items are added to the queue.
There is so much to say here.
There are a few ways
You should only create as many thread handles as you plan on running at the same time, then reuse them when they complete. (Look up thread pool).
This guarantees that you can never have too many running at the same time. This raises the question of funding out when a thread completes. You can have a callback be called just before a thread terminates where a parameter in that callback is the thread handle that just finished. Use Boost bind and boost signals for that. When the callback is called, look for another task for that thread handle and restart the thread. That way all you have to do is add to the "tasks to do" list and the callback will remove the tasks for you. No polling needed, and no worries about too many threads.
I dont understand why Threads have to "sleep" if there is no event in the Application Run Loop. Does this save energy, or memory, or what else?
When there comes in an event from an source input, then it would wake up that Thread again to handle this event. After that, it would sleep again, for the case that there is no more event in the queue waiting to be processed.
Does someone have a good explanation for this sleeping issue?
It's not an issue. It's a good thing. What else would the main thread be doing? It shouldn't be processing long-running tasks - that would reduce the "snappiness" of the UI when a UI event comes in.
It shouldn't be tight-looping until an event comes in - that would take up processor time which can otherwise be sensibly used by other applications.
Sleeping (or rather waiting) is exactly what you want it to do - so it can wake up as soon as it has useful work to do, but otherwise doesn't impact the system.
A sleeping thread allows an OS scheduler (a subsystem which allocates CPU time to threads) to run other threads.
As others have said, putting the thread to sleep allows other threads to be executed.
I'll add that since you are probably referring to the iPhone (based on most of your other questions) this will also be useful even if no other threads need to run as the CPU power consumption will drop when it is idle.