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 9.9k 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.
  • M Offline
    M Offline
    mrjj
    Lifetime Qt Champion
    wrote on 3 Jan 2017, 06:40 last edited by
    #2

    Hi

    Imagine that list_of_names is a list of names

    Yes that totally works for me ;)

    It sounds high level and nice java class,
    not sure Qtt can match that 100% but it seems in function the same
    as
    http://doc.qt.io/qt-5/qtconcurrent-index.html
    with
    http://doc.qt.io/qt-5/qtconcurrent.html#map

    But I didnt see a way to add extra parameters :(

    1 Reply Last reply
    1
    • D Offline
      D Offline
      Defohin
      wrote on 3 Jan 2017, 06:51 last edited by Defohin 1 Mar 2017, 06:52
      #3

      I tried that way, but it crashed:

      QStringList names = { "john", "jane" };
      QString extra = "doe";
      
      auto example = [=] (const QString &name) {
          qDebug() << name << extra;
      };
      
      QtConcurrent::map(names, example);
      

      I thought about using foreach and QtConcurrent::run but I will have to call waitForFinished.

      QStringList names = { "john", "jane" };
      QString extra = "doe";
      
      auto example = [=] (const QString &name, const QString &extra) {
          qDebug() << name << extra;
      };
      
      foreach (QString name, names) {
          QFuture<void> result = QtConcurrent::run(example, name, extra);
          result.waitForFinished();
      }
      

      I don't know if the way I made can lead me to problems, a problem I can see already is: How can I pause them if it's a loop? For instance...

      What you think about that?

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mrjj
        Lifetime Qt Champion
        wrote on 3 Jan 2017, 07:35 last edited by
        #4

        Hmm that was odd. does look ok.
        will names survive the scope?

        Well the foreach is not bad but dont
        result.waitForFinished();

        block the GUI thread ?

        D 1 Reply Last reply 3 Jan 2017, 07:40
        0
        • M mrjj
          3 Jan 2017, 07:35

          Hmm that was odd. does look ok.
          will names survive the scope?

          Well the foreach is not bad but dont
          result.waitForFinished();

          block the GUI thread ?

          D Offline
          D Offline
          Defohin
          wrote on 3 Jan 2017, 07:40 last edited by Defohin 1 Mar 2017, 07:41
          #5

          @mrjj What you mean with names surviving the scope? I don't know what happens, it just crashes.
          The second option seems to be more "the right way" cause I'm passing the values as argument not capturing it in a lambda, also I can create a method and call, the first option I can't call a method.
          I tried this:

          auto example = [=] (const QString &name, const QString &extra) {
              for (int i = 0; i < 9999; ++i) {
                  qDebug() << name << extra;
              }
          };
          

          In the second option to see if it blocks the gui thread but I'm able to move it, I don't know if I'm testing the right way.

          edit

          I just realized that it does block the gui thread, I incremented the 9999 to 9999999 and well... nothing shows.

          What can I do?

          K 1 Reply Last reply 3 Jan 2017, 07:43
          0
          • D Defohin
            3 Jan 2017, 07:40

            @mrjj What you mean with names surviving the scope? I don't know what happens, it just crashes.
            The second option seems to be more "the right way" cause I'm passing the values as argument not capturing it in a lambda, also I can create a method and call, the first option I can't call a method.
            I tried this:

            auto example = [=] (const QString &name, const QString &extra) {
                for (int i = 0; i < 9999; ++i) {
                    qDebug() << name << extra;
                }
            };
            

            In the second option to see if it blocks the gui thread but I'm able to move it, I don't know if I'm testing the right way.

            edit

            I just realized that it does block the gui thread, I incremented the 9999 to 9999999 and well... nothing shows.

            What can I do?

            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 3 Jan 2017, 07:43 last edited by
            #6

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

            Read and abide by the Qt Code of Conduct

            D 1 Reply Last reply 3 Jan 2017, 07:52
            1
            • M Offline
              M Offline
              mrjj
              Lifetime Qt Champion
              wrote on 3 Jan 2017, 07:51 last edited by
              #7

              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 1 Reply Last reply 3 Jan 2017, 07:53
              1
              • K kshegunov
                3 Jan 2017, 07:43

                @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 3 Jan 2017, 07:52 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
                • M mrjj
                  3 Jan 2017, 07:51

                  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 3 Jan 2017, 07:53 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 3 Jan 2017, 07:54 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?

                    M 1 Reply Last reply 3 Jan 2017, 08:00
                    0
                    • D Defohin
                      3 Jan 2017, 07:54

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

                      What can I do?

                      M Offline
                      M Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on 3 Jan 2017, 08:00 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 3 Jan 2017, 08:04
                      0
                      • M mrjj
                        3 Jan 2017, 08:00

                        @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 3 Jan 2017, 08:04 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.

                        :(

                        M 1 Reply Last reply 3 Jan 2017, 08:08
                        0
                        • D Defohin
                          3 Jan 2017, 08:04

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

                          :(

                          M Offline
                          M Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on 3 Jan 2017, 08:08 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 3 Jan 2017, 08:12 last edited by Defohin 1 Mar 2017, 08:13
                            #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 M V 3 Replies Last reply 3 Jan 2017, 08:20
                            0
                            • D Defohin
                              3 Jan 2017, 08:12

                              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 3 Jan 2017, 08:20 last edited by Devopia53 1 Mar 2017, 08:20
                              #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 3 Jan 2017, 08:23
                              0
                              • D Defohin
                                3 Jan 2017, 08:12

                                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.

                                M Offline
                                M Offline
                                mrjj
                                Lifetime Qt Champion
                                wrote on 3 Jan 2017, 08:20 last edited by
                                #16

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

                                1 Reply Last reply
                                0
                                • D Devopia53
                                  3 Jan 2017, 08:20

                                  @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 3 Jan 2017, 08:23 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.

                                  M 1 Reply Last reply 3 Jan 2017, 08:24
                                  0
                                  • D Defohin
                                    3 Jan 2017, 08:23

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

                                    M Offline
                                    M Offline
                                    mrjj
                                    Lifetime Qt Champion
                                    wrote on 3 Jan 2017, 08:24 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 3 Jan 2017, 08:25
                                    0
                                    • M mrjj
                                      3 Jan 2017, 08:24

                                      @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 3 Jan 2017, 08:25 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
                                        3 Jan 2017, 08:12

                                        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.

                                        V Offline
                                        V Offline
                                        VRonin
                                        wrote on 3 Jan 2017, 08:27 last edited by VRonin 1 Mar 2017, 08:43
                                        #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 3 Jan 2017, 08:40 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

                                          11/35

                                          3 Jan 2017, 08:00

                                          24 unread
                                          • Login

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