Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Concurrent map equivalent
QtWS25 Last Chance

Concurrent map equivalent

Scheduled Pinned Locked Moved Solved General and Desktop
35 Posts 5 Posters 9.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Devopia53

    @Defohin

    like this:

    QStringList names = { "john", "jane" }; // global or member variable
    
    void YourClass::startJobs()
    {
        QString extra = "doe";
    
        auto example = [extra] (QString &name) {
            qDebug() << name << extra;
        };
    
        QFuture<void> future = QtConcurrent::map(names, example);
    }
    
    
    D Offline
    D Offline
    Defohin
    wrote on last edited by
    #17

    @Devopia53 It's still crashing for me.
    @mrjj I don't want to use cancel, as i said, I just want to run in parallel the method for each item of a string list and pass a few additional arguments. No need to cancel.

    mrjjM 1 Reply Last reply
    0
    • D Defohin

      @Devopia53 It's still crashing for me.
      @mrjj I don't want to use cancel, as i said, I just want to run in parallel the method for each item of a string list and pass a few additional arguments. No need to cancel.

      mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #18

      @Defohin said in Concurrent map equivalent:

      No need to cancel.

      By cancel i mean to terminate before its finished. Like closing program.
      In that regards you need "cancel" :)

      D 1 Reply Last reply
      0
      • mrjjM mrjj

        @Defohin said in Concurrent map equivalent:

        No need to cancel.

        By cancel i mean to terminate before its finished. Like closing program.
        In that regards you need "cancel" :)

        D Offline
        D Offline
        Defohin
        wrote on last edited by
        #19

        @mrjj Yes, if the application is closed I want to finish the threads as well. I thought it was a default behavior.

        Can you give me an example of what I can do? I'm trying to use QRunnable, but I have no idea if it's going to work.

        1 Reply Last reply
        0
        • D Defohin

          I don't want the pause, continue or the stop function, I just want to run a list of string over a method and pass additional arguments to it in parallel.
          Using QtConcurrent::map won't work cause I can't pass additional arguments.
          Using QtConcurrent::run won't work cause I'll need to call waitForFinished and it will block the GUI thread... (QFutureWatcher::cancel or QFuture::cancel won't work either cause it's not possible to cancel a QFuture returned by QtConcurrent::run)...

          What can I do? I'm out of ideas.

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #20

          @Defohin said in Concurrent map equivalent:

          Using QtConcurrent::map won't work cause I can't pass additional arguments.

          Just use a function object

          struct MapHelper{
          MapHelper(){}
          QString m_additionalArgument1;
          QString m_additionalArgument2;
           typedef QString result_type;
              QString operator()(const QString &val)
              {
                  return m_additionalArgument1+val+additionalArgument2;
              }
          }
          
          MapHelper helper; // TODO: make sure to manage its lifecycle
          helper.m_additionalArgument1 = "Prefix ";
          helper.m_additionalArgument2 = " Suffix";
          QtConcurrent::map(list_of_names,helper);
          

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          3
          • D Offline
            D Offline
            Defohin
            wrote on last edited by
            #21

            @VRonin How to get the return from each one now?

            struct NameHelper
            {
                NameHelper(const QString &extra) : _extra(extra) { }
            
                typedef QString result_type;
            
                QString operator()(const QString &name)
                {
                    return QString("Hello %1 %2").arg(name).arg(_extra);
                }
            
                QString _extra;
            };
            
            QStringList names = { "john", "jane" };
            QString extra = "doe";
            
            QFuture<QString> example = QtConcurrent::mapped(names, NameHelper(extra));
            

            example.result() is returning only "Hello john doe".

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #22

              You can achieve the same with C++11 std::bind:

              QString concatenate(const QString& prefix,const QString& val,const QString& suffix){return prefix+val+suffix;}
              QtConcurrent::mapped(list_of_names,std::bind(concatenate,"Prefix ",std::placeholders::_1," Suffix"));
              

              How to get the return from each one now?
              [...]
              example.result() is returning only "Hello john doe".

              use results() instead of result()

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              2
              • D Offline
                D Offline
                Defohin
                wrote on last edited by
                #23

                It's working nicely, but one last question; Is it GUI blocking? I tried to use a for loop inside of the function and it's now showing anything until it's finished.

                VRoninV 1 Reply Last reply
                0
                • D Defohin

                  It's working nicely, but one last question; Is it GUI blocking? I tried to use a for loop inside of the function and it's now showing anything until it's finished.

                  VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by VRonin
                  #24

                  @Defohin said in Concurrent map equivalent:

                  Is it GUI blocking?

                  no, unless you force it to be

                  I tried to use a for loop inside of the function

                  could you post the code?

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    Defohin
                    wrote on last edited by
                    #25
                    struct NameHelper
                    {
                        NameHelper(const QString &extra) : _extra(extra) { }
                    
                        typedef QString result_type;
                    
                        QString operator()(const QString &name)
                        {
                            for(int i = 0; i < 999999; ++i) {
                                qDebug() << "block";
                            }
                    
                            return QString("Hello %1 %2").arg(name).arg(_extra);
                        }
                    
                        QString _extra;
                    };
                    
                    QStringList names = { "john", "jane" };
                    QString extra = "doe";
                    
                    QFuture<QString> example = QtConcurrent::mapped(names, NameHelper(extra));
                    
                    1 Reply Last reply
                    0
                    • VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by
                      #26

                      operator() will be executed in another thread, it will not block the GUI thread, it will not return until completed (of course)

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      D 1 Reply Last reply
                      0
                      • VRoninV VRonin

                        operator() will be executed in another thread, it will not block the GUI thread, it will not return until completed (of course)

                        D Offline
                        D Offline
                        Defohin
                        wrote on last edited by
                        #27

                        @VRonin But why is it not appearing the window If it's running in another thread?

                        VRoninV 1 Reply Last reply
                        0
                        • D Defohin

                          @VRonin But why is it not appearing the window If it's running in another thread?

                          VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by
                          #28

                          @Defohin said in Concurrent map equivalent:

                          But why is it not appearing the window If it's running in another thread?

                          WOW! we are taking this on a whole new level here! you need a QFutureWatcher on the QFuture and a slot connected to the resultReadyAt signal to display the results in the GUI

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply
                          2
                          • D Offline
                            D Offline
                            Defohin
                            wrote on last edited by
                            #29

                            You are a god, thank you.

                            1 Reply Last reply
                            0
                            • VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by
                              #30

                              I definitely am not, trust me.

                              Just as a final remark, in your case, if you can use C++11, I'd use std::bind over the function object

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              1 Reply Last reply
                              1
                              • D Offline
                                D Offline
                                Defohin
                                wrote on last edited by
                                #31

                                I'm using std::bind now... I realized something:
                                THe threads is not closing if the application closes, meaning that if I close the window it will still open. (if I do a heavy work inside the called function).

                                1 Reply Last reply
                                0
                                • VRoninV Offline
                                  VRoninV Offline
                                  VRonin
                                  wrote on last edited by
                                  #32

                                  Since you are using mapped you can call cancel() to signal to abort the calculation

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  D 1 Reply Last reply
                                  0
                                  • VRoninV VRonin

                                    Since you are using mapped you can call cancel() to signal to abort the calculation

                                    D Offline
                                    D Offline
                                    Defohin
                                    wrote on last edited by
                                    #33

                                    @VRonin Do I have to connect that to a signal from the window for when it's closing or something?

                                    1 Reply Last reply
                                    0
                                    • VRoninV Offline
                                      VRoninV Offline
                                      VRonin
                                      wrote on last edited by
                                      #34
                                      • If you want to stop the calculation when the widget is closed reimplement the closeEvent and call cancel on the QFuture
                                      • If you want to stop the calculation when the widget is destroyed reimplement the destructor and call cancel on the QFuture

                                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                      ~Napoleon Bonaparte

                                      On a crusade to banish setIndexWidget() from the holy land of Qt

                                      D 1 Reply Last reply
                                      2
                                      • VRoninV VRonin
                                        • If you want to stop the calculation when the widget is closed reimplement the closeEvent and call cancel on the QFuture
                                        • If you want to stop the calculation when the widget is destroyed reimplement the destructor and call cancel on the QFuture
                                        D Offline
                                        D Offline
                                        Defohin
                                        wrote on last edited by
                                        #35

                                        @VRonin Thank you very much.

                                        1 Reply Last reply
                                        0

                                        • Login

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • Users
                                        • Groups
                                        • Search
                                        • Get Qt Extensions
                                        • Unsolved