How to for QThread and QThreadPool objects wait for thread creation?
-
Please be a little bit more precise - what do you want to achieve and why do you want to wait until a thread is running?
-
Please be a little bit more precise - what do you want to achieve and why do you want to wait until a thread is running?
@Christian-Ehrlicher becouse I want to use wait / waitForDone methods (otherwise it will finish before the worker threads start).
-
I still don't understand your problem. A QQthread emits finished() when it's done. Just connect on this signal and then do whatever you want (e.g. quit your app).
-
I still don't understand your problem. A QQthread emits finished() when it's done. Just connect on this signal and then do whatever you want (e.g. quit your app).
@Christian-Ehrlicher
Main- thread create worker- threads and must be wait while their end of execution. For this I use wait() method, but wait() return true in two case: before starting thread and after end execution. In my program first case done and I have close program without any execution worker- threads. -
@Christian-Ehrlicher
Main- thread create worker- threads and must be wait while their end of execution. For this I use wait() method, but wait() return true in two case: before starting thread and after end execution. In my program first case done and I have close program without any execution worker- threads.@AlekseyB
Hi
Pleases show some code.
Normally one would use the finished() signal to terminate the program calling
quit() on main thread.It sounds your design is more about preventing main() to run out of scope ?
Do you execute app.exec() ? -
@AlekseyB
Hi
Pleases show some code.
Normally one would use the finished() signal to terminate the program calling
quit() on main thread.It sounds your design is more about preventing main() to run out of scope ?
Do you execute app.exec() ?@mrjj For QThreadPool nothing finished() signal.
For my object, developed by inheritance from QThreadPool, I write this methods for waiting all worker- threads:void syncPool::WaitForFinish() { while(!waitForDone(300)) { //process events QApplication::processEvents(); } }
This methods interruption by main- thread for waiting worker- threads, but after creating tasks worker- threads do not have time to create, and this methods close without waiting of execution.
But if I add count QuantityAllTasks and write this:
void syncPool::WaitForFinish() { while(QuantityAllTasks > 0) { //process events QApplication::processEvents(); waitForDone(300); } }
, program successfully run worker- thread and execute them. I not to want add any shared count in my multi- threaded code.
-
Hi @AlekseyB ,
Instead of using QThreadPool directly, use QFuture (http://doc.qt.io/qt-5/qfuture.html) and QFutureWatcher (http://doc.qt.io/qt-5/qfuturewatcher.html). The nice thing about QFuture is using QFutureWatcher that has signals 'started' and 'finished.' You can asynchronously know when your threads start and stop. You can also watch containers full of results! Futures can also return results. Here is a little sample:
connect (m_watcher, &QFutureWatcher <bool>::finished, this, &threadFinished); ... QFuture <bool> future = QtConcurrent::run (this, &func, arg1, ...);
You can now check result or watch for later...
if (future.result ()) { // This will wait until the thread finishes. }
or
m_watcher->setFuture (future); ... bool MyObject::func (arg1, ...) { if (fail) return false; else return true; } void MyObject::threadFinished () { QFutureWatcher <bool>* watcher = dynamic_cast <QFutureWatcher <bool>*) (sender ()); if (watcher && watcher->result ()) { } }
QtConcurrent::run acts like connect and you can use QObject derived classes for worker functions in the run method. I typically use this for running my plugin based file importers.
[Added code tags ~kshegunov]
-
Hi @AlekseyB ,
Instead of using QThreadPool directly, use QFuture (http://doc.qt.io/qt-5/qfuture.html) and QFutureWatcher (http://doc.qt.io/qt-5/qfuturewatcher.html). The nice thing about QFuture is using QFutureWatcher that has signals 'started' and 'finished.' You can asynchronously know when your threads start and stop. You can also watch containers full of results! Futures can also return results. Here is a little sample:
connect (m_watcher, &QFutureWatcher <bool>::finished, this, &threadFinished); ... QFuture <bool> future = QtConcurrent::run (this, &func, arg1, ...);
You can now check result or watch for later...
if (future.result ()) { // This will wait until the thread finishes. }
or
m_watcher->setFuture (future); ... bool MyObject::func (arg1, ...) { if (fail) return false; else return true; } void MyObject::threadFinished () { QFutureWatcher <bool>* watcher = dynamic_cast <QFutureWatcher <bool>*) (sender ()); if (watcher && watcher->result ()) { } }
QtConcurrent::run acts like connect and you can use QObject derived classes for worker functions in the run method. I typically use this for running my plugin based file importers.
[Added code tags ~kshegunov]
@Buckwheat said in How to for QThread and QThreadPool objects wait for thread creation?:
Buckwheat,Thank you!
But In your case I have no process events. My worker- threads send messages to main- thread for information about current stage of working.Start- signal is emitted when this QFutureWatcher starts watching the future set with setFuture(). But this no mean that thread is start working.
I use wait- methods, but they're use my processor to 100%. Why? My post devote by this question was unduly closed (may be bad question ban on this forum). I see that is the other question, but I have no choice and ask here.
-
Hi,
You didn't answer the question: why do you need to block your main thread ?
If you don't want your user to do something before some state is reached, then disable the GUI or put a modal "waiting to be finished" dialog but don't block the event loop.
-
So your worker needs to communicate with the main thread. Yet another reason NOT to wait! If you have to call "processEvents" then you should connect to QFutureWatcher::finished and react when it is done.
You do understand that if you block the main thread, your signals to the main thread will not be processed! Signals across thread boundaries are handled via the event queue. Take @SGaist advice and disable your UI on start of thread and enable on thread finished if you do not want the user to interact with your application while the thread is running.
My typical usage is for file geodetic model loading which could take up to 30 seconds. I cannot have the hardware stop being processed during this time but I do NOT want the user to do anything. So, I disable the main window on startup and re-enable on finished. This allows the main application to still process hardware events from the CAN and serial ports.
-
@Buckwheat said in How to for QThread and QThreadPool objects wait for thread creation?:
Buckwheat,Thank you!
But In your case I have no process events. My worker- threads send messages to main- thread for information about current stage of working.Start- signal is emitted when this QFutureWatcher starts watching the future set with setFuture(). But this no mean that thread is start working.
I use wait- methods, but they're use my processor to 100%. Why? My post devote by this question was unduly closed (may be bad question ban on this forum). I see that is the other question, but I have no choice and ask here.
@AlekseyB said in How to for QThread and QThreadPool objects wait for thread creation?:
I use wait- methods, but they're use my processor to 100%. Why?
You never answered what's this
waitForDone
and how it is implemented. Also note that calling some functionwaitFor***
, won't make it blocking. As I mentioned in your other thread, you can use a semaphore for waiting:// # thread 1 semaphore.acquire(); //< We block here until someone calls release(), or we continue on if someone already did // # thread 2 semaphore.release(); //< Free the waiting thread if it's blocked
My post devote by this question was unduly closed (may be bad question ban on this forum).
Unduly? I don't think so. We don't discriminate in this forum, the question may be bad, may be good, it's still a question. However we do try to keep the place tidy, which excludes posting of multiples of the same question.
I see that is the other question, but I have no choice and ask here.
Which is exactly why I closed your other thread, as the issues you describe as two different problems are rather one.