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. Trying to use QFuture and QFutureWatcher for the first time

Trying to use QFuture and QFutureWatcher for the first time

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 2 Posters 1.7k Views 1 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.
  • PerdrixP Perdrix

    I did precisely that and then extended it until I got a fail.
    D.

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by
    #14

    @Perdrix Ah, well it helps if you say that! I will have a look at your code to see if I can spot something different.....

    1 Reply Last reply
    0
    • PerdrixP Perdrix

      OK I've reduced the replication to a relatively simple case:

      You can find the source files here:
      http://www.perdrix.co.uk/TestQtConcurrent.zip

      If you want the entire MSVC solution, say so and I will zip that up and make it available.
      David

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #15

      @Perdrix said in Trying to use QFuture and QFutureWatcher for the first time:

      You can find the source files here:
      http://www.perdrix.co.uk/TestQtConcurrent.zip

      If I just open it in Chrome nothing happens.
      If I force it to download (it seems to start but never finishes) I get about 4k and then it stops.
      If you want someone to access this then please verify it works for you from an incognito browsing session....
      UPDATE OK, although the download does not finish properly if I rename the temporary .crdownload file to .zip it seems to have content....

      1 Reply Last reply
      0
      • PerdrixP Offline
        PerdrixP Offline
        Perdrix
        wrote on last edited by Perdrix
        #16

        The zip file is only 4kB... - worked for me in an incognito Chrome session on Windows, but did bitch that it wasn't https ...

        D.

        1 Reply Last reply
        0
        • PerdrixP Perdrix

          OK I've reduced the replication to a relatively simple case:

          You can find the source files here:
          http://www.perdrix.co.uk/TestQtConcurrent.zip

          If you want the entire MSVC solution, say so and I will zip that up and make it available.
          David

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #17

          @Perdrix
          So I have copied/pasted the 3 files you supply into their own project.

          I don't even see how what you have supplied would compile. In griddata.h there are two errors:

          • No template named QPromise
          • Use of undeclared identifier std

          These are both visible in Creator. And make sense to me, as the necessary includes are not in griddata.h. That is improved with the addition of #include <QPromise> in griddata.h. (And I had to comment out a couple of other includes.)

          Now I think I am down to a couple of compilation error messages like you have been showing. I will investigate further... :)

          The zip file is only 4kB...

          I know! But for whatever reason my Chrome does not complete the download of this file from you. It seems to get the full content but never sees it finish, so does not rename the temporary download file to the intended .zip. But doing that manually I seem to have the full zip so I am good.

          1 Reply Last reply
          0
          • PerdrixP Offline
            PerdrixP Offline
            Perdrix
            wrote on last edited by Perdrix
            #18

            Don't need a template GridData only uses a reference: QPrimose<void>& promise but won't harm to include it.

            Don't need to do anything for std:: stuff, so long as you call it out by its full name

            JonBJ 1 Reply Last reply
            0
            • PerdrixP Perdrix

              Don't need a template GridData only uses a reference: QPrimose<void>& promise but won't harm to include it.

              Don't need to do anything for std:: stuff, so long as you call it out by its full name

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #19

              @Perdrix

              @Perdrix said in Trying to use QFuture and QFutureWatcher for the first time:

                  void
                      interpolate(QPromise<void>& promise,
                          const std::vector<double>& x, const std::vector<double>& y, const std::vector<double>& z,
                          const std::vector<double>& xg, const std::vector<double>& yg, std::vector<double>& zg,
                          InterpolationType type, float data = 0.0);
              

              All the other std::vector<double>&s are const, but not the final zg one. Intended or not? This is the error.

              If you make that one const too it compiles.

              If you test just

              void
              GridData::interpolate2(QPromise<void>& promise,
                                     const std::vector<double> &x)
              
              QFuture<void>future2 = QtConcurrent::run(&GridData::interpolate2, instance.get(), xValues);
              

              That works. But take out the const and it fails.

              You could have reduced it down to just this parameter type, nothing to do with all the member methods:

              void func1(QPromise<void>& promise, std::vector<double> &xValues)
              {
              }
              
              QFuture<void> fut1 = QtConcurrent::run(func1, xValues);
              

              std::vector<double> &xValues does not pass. Either (or both) of adding in const or removing the & do pass.

              I don't use std::vector and am going leave it to you now. You may need e.g. @Christian-Ehrlicher to explain the deep reason. I am not sure anyway about accessing non-const reference to arrays in the thread(s) run by QtConcurrent. As I wrote, if you can change yours to const std::vector<double>& zg or std::vector<double> zg it won't matter. Though of course we would like to hear from a C++ expert for the definitive explanation!

              Phew!

              And, yes, no, C++ compiler errors, especially with templates, are not the simplest.

              P.S.
              Just this fails in same way:

              void func1(QPromise<void>& promise, int &test)
              {
              }
              
              int test;
              QtConcurrent::run(func1, test);
              

              And again changing func1() to either const int &test or int test works. So nothing to do with std::vector. You evidently cannot pass a mutable reference parameter here, I am thinking QtConcurrent::run() does not allow this because of threading/need to copy requirements? Now that we knows this is the issue we find e.g.
              https://stackoverflow.com/questions/25091518/qt-concurrent-run-pass-value-by-reference-but-the-memory-address-is-different

              QtConcurrent::run creates internal copies of all arguments that you pass to it. Your thread function is then given access to these copies, not to the original arguments. Passing something by raw reference does not prevent creation of a copy. In other words, QtConcurrent::run enforces pass-by-value semantics internally.

              The address that you see in the ref function is the address of that internal copy.

              For this reason, if you specifically want access to the original object, instead of a naked reference you have to use something with pointer semantics or with "copyable reference" semantics.

              That was a few years ago. Perhaps the definitions/compiler now show an attempt to pass a non-const reference as a compile-time error where it used to get through but then did not act as expected?

              1 Reply Last reply
              1
              • PerdrixP Offline
                PerdrixP Offline
                Perdrix
                wrote on last edited by Perdrix
                #20

                Argh! I need that to be a non const vector reference, as the interpolate code populates that vector.

                @JonB Thanks for finding out what was stopping it working! I'd never have guessed that was the problem.

                I've updated the files so it should compile OK on Linux, and refreshed the zip file:
                http://www.perdrix.co.uk/TestQtConcurrent.zip
                @Christian-Ehrlicher Can you advise please?

                Meantime I will change the code to use std::ref(zgEccentricity).

                UPDATE: using std::ref(zgEccentricity) worked fine. May I suggest that some documentation updates to say you can't pass a non-const thing using a normal reference and that using std::ref might be useful. Either that or?
                David

                JonBJ 1 Reply Last reply
                0
                • PerdrixP Perdrix

                  Argh! I need that to be a non const vector reference, as the interpolate code populates that vector.

                  @JonB Thanks for finding out what was stopping it working! I'd never have guessed that was the problem.

                  I've updated the files so it should compile OK on Linux, and refreshed the zip file:
                  http://www.perdrix.co.uk/TestQtConcurrent.zip
                  @Christian-Ehrlicher Can you advise please?

                  Meantime I will change the code to use std::ref(zgEccentricity).

                  UPDATE: using std::ref(zgEccentricity) worked fine. May I suggest that some documentation updates to say you can't pass a non-const thing using a normal reference and that using std::ref might be useful. Either that or?
                  David

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #21

                  @Perdrix said in Trying to use QFuture and QFutureWatcher for the first time:

                  Argh! I need that to be a non const vector reference, as the interpolate code populates that vector.

                  You have just crossed with my final update to my reply. Have a read through the stackoverflow post (or try to find your own), there may be stuff there which allows you to do something, e.g.

                  QtConcurrent::run(func1, std::ref(test));
                  

                  seems to compile against int &test, I don't know anything about std::ref() but it looks good?

                  P.S.
                  Being an originally C person, without all this C++ nonsense, references etc. I bet

                  void func1(QPromise<void>& promise, int *test) {}
                  QtConcurrent::run(func1, &test);
                  

                  would work ;-) [But of course don't do this!]

                  1 Reply Last reply
                  0
                  • PerdrixP Offline
                    PerdrixP Offline
                    Perdrix
                    wrote on last edited by
                    #22

                    I found the line about the use of std::ref in the docs, so it is there, but it is fairly easy to miss it.

                    D.

                    JonBJ 1 Reply Last reply
                    0
                    • PerdrixP Perdrix

                      I found the line about the use of std::ref in the docs, so it is there, but it is fairly easy to miss it.

                      D.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #23

                      @Perdrix
                      It would be good for this thread if you provided the link to whatever you say it says about std::ref() and also pasted the relevant sentence/paragraph here, for others to see in future.

                      1 Reply Last reply
                      0
                      • PerdrixP Offline
                        PerdrixP Offline
                        Perdrix
                        wrote on last edited by Perdrix
                        #24

                        It is buried in the "Additional API Features" section of the doc and says:
                        image.png

                        It should be right up front where QtConcurrent::run() is described, saying very clearly that you must use std:ref(variable) when passing a reference to a modifiable object.

                        JonBJ 1 Reply Last reply
                        0
                        • PerdrixP Perdrix

                          It is buried in the "Additional API Features" section of the doc and says:
                          image.png

                          It should be right up front where QtConcurrent::run() is described, saying very clearly that you must use std:ref(variable) when passing a reference to a modifiable object.

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by
                          #25

                          @Perdrix
                          OK, for whatever reason (maybe misplaced) this appears in subsection https://doc.qt.io/qt-6/qtconcurrentrun.html#using-lambda-functions, for anyone reading this.

                          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