Unsolved A couple quick multithreading questions
-
Hi I am trying to multi-thread a program I'm making which is a file replication/data backup program. I need to be able to cancel the file copying in the middle of its progress. I also need to be able to send signals to the gui thread to update the gui about progress. I've read a lot of material and have come to the conclusion either of the 'permanent' options here http://doc.qt.io/qt-5/threads-technologies.html on the bottom would be the most appropriate. Is this a proper conclusion? Which method - subclassing qthread or moving a qobject worker to a thread - would be better?
I am also wondering if I need to lock my data with a Mutex or not. The only threads are the gui thread and the worker thread doing the file copying. When the copying occurs the gui thread is completely locked down so none of the objects of the class the backup job data (source/target/list of files etc) is stored in can be modified by both threads at once. The data about what to backup etc is stored in the class objects and contains QStrings, bools, a QDateTime, ints/qint64s, a QList<QPair<QString, QString> >, 3 QStringLists, and a QList<dir>. As the code is now I'll be modifying the QList<QPair<QString, QString> > guy in the worker thread to contain what needs to be backed up and a couple ints to store amount of bytes to be backed up then just reading the QList and doing the actually data copying. In the end I update the job object with a last run datetime converted to qint64 (the only modification that needs to be passed back to the main gui thread). So basically just do I need to use a mutex or not since there is no concurrent modification going on (or reading either) among the threads.
Also can I pass the data backup job objects by reference to the worker thread?
And is there a way to cancel a thread mid-operation without qApp->processEvents()? I did find an example in the book c-gui-programming-with-qt-4-2ndedition that just modifies a boolean stop variable via a method in the thread object and the book said the method can be called at any time; however the other examples I saw online used slots.
Anything else to know? Thanks! Perhaps the QT thread documentation could be updated to contain some of these concepts to be more thorough...
-
@Crag_Hack "When the copying occurs the gui thread is completely locked down" - in this case, why do you need another thread? Just use the GUI thread if it is OK to block it. But I'm not sure how the user is going to abort file copying if you block the UI.
-
So if I don't use another thread/qappprocessevents/qtimer the gui thread hangs during the file copying. The only part of the gui thread that isn't locked down is the cancel button which alters a boolean variable and passes it to the worker thread.
-
Hi,
One thing to take into account when copying files: if you want to make this interruptible, you should write your own function to copy parts of the file that will check the stopping flag before each block.
-
Thanks SGaist already done :) Any input on the other guys?
-
Most important questions are just the mutex thing and reference passing.. the other stuff I can figure out on my own...
-
@Crag_Hack said:
which alters a boolean variable
Make sure this is atomic to avoid race conditions, use
std::atomic_bool
instead ofbool
subclassing qthread or moving a qobject worker to a thread
use moving, do not subclass QThread
Also can I pass the data backup job objects by reference to the worker thread?
All of your data is either small (32/64 bits) or implicidly shared so the hassle of making 1000% sure there are no race conditions/deadlock is not worth the advantage of passing things by reference
So basically just do I need to use a mutex or not since there is no concurrent modification going on (or reading either) among the threads
if you load the data from the widget and pass it as value to the thread you should not need mutex (to be clear, the worker thread should never directly access any widget in the gui but this is a general rule)
-
Thanks VRonin.
@VRonin said:
All of your data is either small (32/64 bits) or implicidly shared so the hassle of making 1000% sure there are no race conditions/deadlock is not worth the advantage of passing things by reference
You're saying it's a better choice to pass by reference correct? (Also that the extra precautions are just not worth hassle?)
if you load the data from the widget and pass it as value to the thread you should not need mutex (to be clear, the worker thread should never directly access any widget in the gui but this is a general rule)
Also regarding the mutex are you referring to passing as a value parameter? Does what you said apply to reference parameters as well considering the gui is locked down which prevents concurrent access to the job objects?
Any books/online tutorials you could recommend to learn more about threading like what you mentioned - deadlocks/race conditions ? I've already scoured the online qt thread documentation.