Okay long-story-short, I am making program which has to deal with Tkinter GUI and Networking. So I made the client-server connectivity on the main thread and a additional thread will run parallel to the main thread which will execute all the GUI Tkinter based work. Now I have reached a Deadlock situation where I need a call a function in the GUI thread(2nd thread) from the main thread. I am open to suggestions to do something like that or achieve something like what I described above.
Thanks for your answers in advance! Cheers!
Related
Sorry for my bad English.
I made a file hashing app with tkinter and python3 but as soon it start hashing files User Interface get freeze.
How can I prevent it...?
Multithreading for I/O operations and Multiprocessing for CPU intensive tasks. Read What are the differences between the threading and multiprocessing modules?
See also Tkinter: How to use threads to preventing main event loop from "freezing"
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.
This is my first experience on threading with Qt, so bear with me.
I have a singleton "system" object which periodically executes a heavy piece of code.
I control the system singleton from my UI, but the system is not aware of the UI.
I create a thread in my main, and then move the system to it:
QThread systemThread;
System::instance()->moveToThread(&systemThread);
systemThread.start();
qApp.exec();
The UI hangs until the system's periodical processing cycle is complete.
I have also tried to subclass QThread and calling exec from the run method.
What could be the problem? I'm certainly doing something wrong.
Best regards
See the excellent article about Threads, Events and QObjects in the Qt developer wiki. Something seems to be wrong with the thread affinity, you can check that with QObject::thread().
I advice you to follow this guideline from a Qt Developer himself when implementing multithreading: https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong
It is way more effective and painless.
systemThread.start() will start systemThread.run() method in thread so you need to implement it inside run().
To create your own threads, subclass QThread and reimplement run().
Main (function main is there) thread of my program is reserved for non-GUI tasks. It calls a number of lengthy calculation functions. All implemented GUI's have been doing their work in a separate threads.
I'm now going to implement one more GUI using Qt. Qt documentation says all GUI related tasks should be done in main thread.
In my case, inserting occasional QCoreApplication::processEvents() calls in main thread would be virtually useless due to great delays between them.
Is there any way to overcome this constraint of Qt?
Is it impossible to do something non-GUI related in main thread of Qt program?
No, you should be doing your calculations in a separate thread. As you already mentioned, there is a work-around available in QCoreApplication::processEvents(), but it sounds like you're unable to make that work for you.
If you don't want to have to do all the work of setting up a QThread and moving all your code, you may find that the QtConcurrent::run function is useful - it allows you to run a function asynchronously.
A few pointers: You should try and keep your main (GUI) thread as light as possible. Large amounts of IO or calculations should either be done asynchronously using QtConcurrent::run, or run inside a separate QThread. Depending on the complexity of your code, you may be able to get away with the QtConcurrent method.
It's best to offload the long computations onto other threads so the main GUI thread remains responsive. The old-school uniprocessing way of doing things would be be to make sure your computations never run for too long without polling GUI event handler, but that doesn't scale to multi-cores.
Fortunately Qt has excellent threading support. In the past you'd have to roll-you-own system for e.g farming out tasks to a thread-pool using QThread, QMutex, QWaitCondition etc, but recent Qt releases have made things easier with higher level abstractions like QThreadPool, QtConcurrent::run and QFuture.
I don't know how things will go if you call QApplication::exec() from another thread, which then becomes your gui thread. Just an idea.
(Let us know if it works, it'd be interesting...)
The concept of main thread is not clearly defined in Qt documentation. Actually, the main thread of a process (process that executes the Process.run function) can be different from the main Qt thread (thread that instantiates the first Qt object like a QApplication), although both "main" threads are often the same one.
Example of valid code structure:
function below will run in the process' non-main thread 'thread-1', that will become immediately Qt's main thread.
def startThread1():
app = QApplication(sys.argv)
app.exec_() # enter event loop
code below run in process' main thread, not to be confused with the main Qt and unique GUI thread of the process.
thread1 = Thread(target=self.startThread1)
thread1.start()
input('I am busy until you press enter')
I just implemented a thread pool like described here
Allen Bauer on thread pools
Very simple implementation, works fine, but my application no longer shuts down. Seems that two worker threads (and one other thread, I guess the queuing thread) stuck in the function
ntdll.ZwRemoveIoCompletion
I remember to have read something about IO completions in the help entry for QueueUserWorkItem (the WinAPI function used in the thread pool implementation), but I couldn't understand it properly. I used WT_EXECUTELONGFUNCTION for my worker threads since execution can take a while and I want a new worker thread created instead of waiting for the existing ones to finish. Some of the tasks assigned to the worker threads perform some I/O stuff. I tried to use WT_EXECUTEINIOTHREAD but it does not seem to help.
I should mention that the main thread waits for entry to a critical section witht the call stack being
System.Halt0, System.FinalizeUnits, Classes.Finalization, TThread.Destroy,
RtlEnterCriticalSection, RtlpWaitForCriticalSection
Any ideas what I'm doing wrong here? Thanks for your help in advance.
To make sure the worker threads shut down, you need to have some way of waking them up if they are waiting on the empty IO completion port. The simplest way would seem to be to post a NULL message of some kind to the port - they should then treat this as a signal to halt in an orderly fashion.
You must leave from the critical section before you can enter again. So the problem is inside a lock.
In some thread:
EnterCriticalSection(SomeCriticalSection);
sort code...
LeaveCriticalSection(SomeCriticalSection);
In some other thread:
EnterCriticalSection(SomeCriticalSection);
clean up code...
LeaveCriticalSection(SomeCriticalSection);
If the sort code is running in the first thread and the second thread try to run the clean up code the second thread will wait until the sort code finish and you leave the critical section. Only after leaving the critical section you can enter the same critical section. I hope this will help you narrow down the deadlock code because it is inside a critical section.
To get the completion port handle you can save it's handle when you create the completion port:
FIoCPHandle := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0 , 0, FNumberOfConcurrentThreads);
When using QueueUserWorkItem, as long as the worker threads have been returned to the thread pool, you should not have to do anything to shut them down. The WT_EXECUTEDEFAULT component of the thread pool queues the work items up onto an I/O completion port. This port is part of the thread pool's internal implementation and is not accessible to you.
Could you provide some more detailed call stacks for the threads that appear to be stuck? It would make this problem much easier to diagnose.