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
Forum Updated to NodeBB v4.3 + New Features

Concurrent map equivalent

Scheduled Pinned Locked Moved Solved General and Desktop
35 Posts 5 Posters 10.4k Views 3 Watching
  • 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.
  • kshegunovK kshegunov

    @Defohin said in Concurrent map equivalent:

    What you mean with names surviving the scope?

    He means this from the docs for QtConcurrent::map:

    Calls function once for each item in sequence. The function is passed a reference to the item, so that any modifications done to the item will appear in sequence.

    Once you leave the scope of the function, the reference you'd passed is invalid and the program crashes. Perhaps you need mapped() instead?

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

    @kshegunov I tried using mapped but it doesn't work with lambdas.

    I removed the waitForFinished and it's working... but I don't know if something bad will happen by doing that...

    1 Reply Last reply
    0
    • mrjjM mrjj

      Hi
      I think concurrent will be more fun as it dont block the GUI thread.
      as in.

      void mapFunction(int& n) {
      qDebug() << n;
      }
      
      void test() {
        QList<int>* vectorOfInts =  new QList<int>;
        for (int i = 0; i < 1000; i++)
          vectorOfInts->push_back(i);
      
        QFuture<void> future = QtConcurrent::map(*vectorOfInts, mapFunction);
      
      } // end of scope
      
      D Offline
      D Offline
      Defohin
      wrote on last edited by
      #9

      @mrjj Your way works fine but I can't pass additional parameters. The second approach is not blocking anymore cause I removed the waitForFinished but I don't know if it's going to be a bad thing...

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

        I just realized something... if though it's working, if I close the window it will continue running...

        What can I do?

        mrjjM 1 Reply Last reply
        0
        • D Defohin

          I just realized something... if though it's working, if I close the window it will continue running...

          What can I do?

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

          @Defohin
          Hi , i think you can cancel via
          http://doc.qt.io/qt-5/qfuture.html#cancel
          http://doc.qt.io/qt-5/qfuturewatcher.html#cancel

          I think you need to use QFutureWatcher if u dont use waitForFinished.
          All credits to @kshegunov :)

          D 1 Reply Last reply
          0
          • mrjjM mrjj

            @Defohin
            Hi , i think you can cancel via
            http://doc.qt.io/qt-5/qfuture.html#cancel
            http://doc.qt.io/qt-5/qfuturewatcher.html#cancel

            I think you need to use QFutureWatcher if u dont use waitForFinished.
            All credits to @kshegunov :)

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

            @mrjj

            Be aware that not all asynchronous computations can be canceled. For example, the QFuture returned by QtConcurrent::run() cannot be canceled; but the QFuture returned by QtConcurrent::mappedReduced() can.

            :(

            mrjjM 1 Reply Last reply
            0
            • D Defohin

              @mrjj

              Be aware that not all asynchronous computations can be canceled. For example, the QFuture returned by QtConcurrent::run() cannot be canceled; but the QFuture returned by QtConcurrent::mappedReduced() can.

              :(

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

              @Defohin
              Oh. not all can be canceled. :(
              Well if u need to be able to stop at random then
              threads might be the best solution.

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

                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.

                D mrjjM VRoninV 3 Replies 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.

                  D Offline
                  D Offline
                  Devopia53
                  wrote on last edited by Devopia53
                  #15

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

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

                    Hi
                    If cancel is a MUST have, then QThreads seems the only option :(

                    1 Reply Last reply
                    0
                    • 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

                                          • Login

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