Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

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


  • Lifetime Qt Champion

    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...


  • Lifetime Qt Champion

    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.

  • Lifetime Qt Champion

    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.


Log in to reply