Run thread B in a thread A and update UI connecting B to a slot
-
Hello everyone <3
I have a question about thread. It is known that you can't do some stuff over the UI inside a thread. Otherwise, it will led to very bad issues. So I can connect my thread to a function to update the UI and it works fine.
Now, if I launch a thread A. Inside the thread A, I launch a thread B. I connect the thread B to a slot my_slot() that modify the UI. Is my_slot() will be run in the thread A or in the main UI loop ?
I tried and I don't have problem but I want to be sure. I think the answer is here : https://doc.qt.io/qt-5/qt.html#ConnectionType-enum but I dont understand.
Thank you very much for your help
-
Hi and welcome to devnet,
How did you implement that ?
How are you doing the connection ?If properly done, the slot should be executed in the GUI thread.
-
There are a lot of codes. It's written in PyQt. I can try to explain my implementation and share some code or I can share with you the PR in github. You can find the PR on https://github.com/borgbase/vorta/pull/1045 Tthere is a nice UML graphic with comment on this link that explains my implementation. If you need more details, I can explain.
-
If I get the idea correctly you want to do some task parallelisation, correct ?
If so, I must say that the current naming you are using for the various objects is a bit confusing.
From the looks of it, you seem to want to be able to trigger several BorgThreads at the same time, am I right ?
-
If I get the idea correctly you want to do some task parallelisation, correct ?
Yes
If so, I must say that the current naming you are using for the various objects is a bit confusing.
Maybe that VortaQueue is not the right one since VortaQueue contains a dictionary of queues. What do you propose as names ? Maybe JobsManager instead of VortaQueue. _Queue instead of _QueueScheduler.
From the looks of it, you seem to want to be able to trigger several BorgThreads at the same time, am I right ?
Yes and No. Actually, you can put whatever you want in the run method of a JobQueue. So yes the main goal is to launch a BorgThread in run(). I just implemented a more general concept to clearly put a frontier between BorgThread and VortaQueue. If BorgThread implementaion changes, the queues manager (VortaQueue) must not be impacted.
The idea is that you have sites (_QueueScheduler) and on each site you can run Job. VortaQueue manages these sites by creating or removing them and is the only way to add a Job to the right site. -
You have to define what a Job is, then a Queue and the Queue Manager.
This will give you the base names.
I would also see how to properly cancel the jobs without requiring too convoluted techniques.
Start with a simple job for the BorgThread with as explained simple cancelling implementation.
-
You have to define what a Job is, then a Queue and the Queue Manager.
Is it a question ?
I would also see how to properly cancel the jobs without requiring too convoluted techniques.
?
Start with a simple job for the BorgThread with as explained simple cancelling implementation.
I dont understand what "a simple job for the BorgThread" means. Whats the problem with cancel ?
And, is it safe to call a slot in the thread B ?
-
You have to define what a Job is, then a Queue and the Queue Manager.
Is it a question ?
I would also see how to properly cancel the jobs without requiring too convoluted techniques.
?
Start with a simple job for the BorgThread with as explained simple cancelling implementation.
I dont understand what "a simple job for the BorgThread" means. Whats the problem with cancel ?
And, is it safe to call a slot in the thread B ?
@BabaCo said in Run thread B in a thread A and update UI connecting B to a slot:
You have to define what a Job is, then a Queue and the Queue Manager.
Is it a question ?
Rather a suggestion with regard to the current naming to allow a better view of the future implementation.
@BabaCo said in Run thread B in a thread A and update UI connecting B to a slot:
I would also see how to properly cancel the jobs without requiring too convoluted techniques.
?
Your are using a global Boolean variable to determine if a task is running which looks strange. You may have several tasks so why use such a global ?
Your cancel function does an if True which is rather strange.
Hence my suggestion to take the time to go back to the drawing board to build that part in maybe a simpler fashion. Maybe go from the bottom up. Define in the most simple way the Job that will run the BorgThread as well as as a second one for another task. Make them cancelable and from there you can extract a base class and then build the queue handling.
-
Rather a suggestion with regard to the current naming to allow a better view of the future implementation.
Ok yes I changed the names.
Your are using a global Boolean variable to determine if a task is running which looks strange. You may have several tasks so why use such a global ?
Your cancel function does an if True which is rather strange.
The PR is not done yet. The cancel method you talk about is never called and Will be removed before merging. I changed the condition to True at the very beginning to avoid some problems in the UI but this cancel method is not used. It is to the JobQueue inherited class to implement the cancel method. You can see a correct implemented exemple in CreateJobSched (just pushed, I also renamed the classes). The cancel method is in CreateJobSched.
The global was also an old code. But it is still used only for the user. When there is a running Job, the user cant start another backup. So the global only disabled the "Start backup" button. Only the scheduler (backgroud automatic backups) has the ability to run Job concurrently. The scheduler never checks the global boolean. It's a choice and it makes sense (The user can push 100 times the push buttons if he wants, the scheduler can't).
The global will be moved in the JobsManager and Will be implemented with a mutex like before. -
You're welcome !
You shouldn't need to have a global. That looks like a design issue waiting to bite you, especially in multithreaded case.
I just thought of something, since you are using Qt, you might want to check KDE's threadweaver.
It looks like the framework already implements what you want to do.