Unsolved Real QConcurrent usage - suggestions wanted
-
After some struggle I finally have test code implementing QConcurrent and performing as desired.
There was a reason for all of this and I am not sure how to switch from purely academical / test implementation of all what is associated with QConcurrent.My initial understanding was to use QConcurrent to create additional thread to have a time consuming function running in separate thread from main process thread. ( I do accept the fact that the user has to wait for it to finish irregardless if it is running in main process thread or in the background)
That works in test code, with unexpected "benefit " of actually running four threads instead of single one.
Now I like to have QConcurrent code run the actual time consuming function.
I assume that I can add " execute time consuming function" line of code somewhere , but I have to make sure it actually runs in QConcurrent thread and not in main process thread AND keeps updating the QProgressDialog at reasonable intervals.Minor issue - the "timer consuming function" emits only single "I am finished" signal , hence I need to emulate the 1 seconds tick in sort-of parallel real time way.
So - I am primarily asking for suggestion WHERE to insert the "start time consuming function" into existing QConcurrent code.
Or is it cleaner to start the time consuming function in main process and just implement the delay / progress only in QConcurrent code ?
Again - I do accept the fact that the user has to wait for the time consuming function to finish irregardless if it is running in main process thread or in the background.
Current basic pseudo-code of usage of QConcurrent
set process total delay combination of # of iterations and single delay time build QVector array of iterations build instance of QProgressDialog set QProgressDialog parameters build instance of QFutureWatcher set "connect" SIGNAL / SLOT functions set QFutureWatcher ( QConcurrent , QVector ) execute QProgressDialog watch for smoke...
Cheers
-
Hi,
You can run one single function in a single thread using QtConcurrent::run. If you have several thread used, you are likely using QtConcurrent::map which is going to call the function for each element in the container you passed to it.
So the question is: which of these two use cases are you really after ? From the looks of it, it seems to be the first one with if possible a report of the progress of the long running function.
In any case, you do not want to start the long running function in the main thread. Having to wait is not an issue unless your application looks frozen which will be the case if you call your long function in the main thread.
-
@SGaist said in Real QConcurrent usage - suggestions wanted:
Hi,
You can run one single function in a single thread using QtConcurrent::run. If you have several thread used, you are likely using QtConcurrent::map which is going to call the function for each element in the container you passed to it.
So the question is: which of these two use cases are you really after ? From the looks of it, it seems to be the first one with if possible a report of the progress of the long running function.
In any case, you do not want to start the long running function in the main thread. Having to wait is not an issue unless your application looks frozen which will be the case if you call your long function in the main thread.
You are , as always, absolutely correct. When I first test run the function my main form turned gray and basically was "frozen" until the function completed.
That behavior prompted me to look for an alternative.
So I if I continue to run the function in main thread I have not really changed anything as far as user is concerned.If I get your suggestion correctly - the function needs to be part of the QConcurrent map / vector array creation.
I am little confused how "map" actually works , I assume that it would have only one map / vector to execute the function and rest of them being the "timing ticks".
Am I correct ?
I would not want to restart the function during each iteration. However the 1 second delay function needs to be treated / restarted as it is now.Then since I now know that QConcurret runs all CPU cores as default I may get brave and try to convince QConcurnet to run only one thread of the function. It really does not matter / make much difference to run all (default) four CPU cores / threads.
I may have to resurrect my search for HCI inquiry function source code - it would be nice to have real SIGNAL to track the progress of the HCI function.
It looks as this project never ends...
-
The map method will execute the function once for each item in the container. This will match your "ticks".
If using QFutureWatcher, you can monitor that. As the documentation says however, depending on the speed of the ticks, it will do some throttling to avoid overloading the event loop.
Can you explain why you need that delay function ?
It seems that you need to somehow slowdown map hence it seems that it might not be the best solution for you.
If you need to execute that function for each item in the container but one after the other, then run would make more sense.
-
@SGaist said in Real QConcurrent usage - suggestions wanted:
The map method will execute the function once for each item in the container. This will match your "ticks".
If using QFutureWatcher, you can monitor that. As the documentation says however, depending on the speed of the ticks, it will do some throttling to avoid overloading the event loop.
Well, if posting an event every second is too much to overload the system - I'll get another hobby... perhaps stamp collecting ?
Can you explain why you need that delay function ?
It was basically an emulator of the real function taking up to 16 seconds to complete. And of course it also serves as progress indicator , roughly once very second.
'It seems that you need to somehow slowdown map hence it seems that it might not be the best solution for you.
If you need to execute that function for each item in the container but one after the other, then run would make more sense.
Before I read your reply I did this:
qDebug()<< "setup to run time consuming function "; futureWatcher.setFuture(QtConcurrent::run(TestFunction)); qDebug()<< "test apply delay function "spin" to each vector"; // test map vector array with spin function futureWatcher.setFuture(QtConcurrent::map(vector, spin)); ```' 'Basically combination of QConcurrent run and map. I cannot believe it is so simple. To reply to your post - the "spin / AKA 1 second delay " is just to monitor the actual progress of time consuming function. Using "best guess" and eventually stopping after the only SIGNAL emitted by the time consuming function is received. I need to work on that since the actual time of the ":scan" function is hardware dependent. So this "progress " is really just best guess - for now.
-
When you have an operation that you do not really know the length like that one, you can use an infinite progress bar that will show that something is going on. For that you can use QProgressDialog with a range set to 0 - 0.