Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Need advice with QtConcurrency & lambda expression
Forum Updated to NodeBB v4.3 + New Features

Need advice with QtConcurrency & lambda expression

Scheduled Pinned Locked Moved Solved C++ Gurus
5 Posts 2 Posters 782 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.
  • R Offline
    R Offline
    r3d9u11
    wrote on last edited by r3d9u11
    #1

    Hello. I've faced some trouble with lambda function and QtConcurrent, because I can't get value of shared variable inside the lambda? Seems like there is value of address in memory instead of value of variable:

    Here is some examples:

    static void calllambda(const qint64 var)
    {
        auto wrong = [&]() { qDebug() <<  var; };
        QtConcurrent::run(wrong); //  output: 140725839328608 (WRONG)
    
        wrong(); // without QtConcurrency works fine, output 123123123 (VALID pass_by_reference)
    
        // pass_by_value as workaround
        auto woraround = [var]() { qDebug() <<  var; };
        QtConcurrent::run(woraround); //  output: 123123123 (VALID pass_by_value)
        auto woraround1 = [](const qint64 var) { qDebug() <<  var; };
        QtConcurrent::run(woraround1, var); // output: 123123123 (VALID pass_by_value)
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        calllambda(123123123);
    
        return a.exec();
    }
    

    in the same time all works fine if I move body of 'calllambda' into the function 'main':

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        const qint64 var = 123123123;
    
        // the same code "QtConcurrency+lambda+pass_by_reference" works fine in main function:
    
        auto wrong = [&]() { qDebug() <<  var; };
        QtConcurrent::run(wrong); // output: 123123123 (VALID pass_by_reference)
    
        return a.exec();
    }
    

    Qt 5.15.0
    Linux KDE Neon x86_64

    Somebody can describe that unobvious behavior?
    Thanks!

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #4

      @r3d9u11 said in Need advice with QtConcurrency & lambda expression:

      but it doesn't metter for pure C++

      This is a pure c++ problem...

      var is local inside calllambda() and gets destroyed when the function exits. Then later the lambda is called in another thread and accesses garbage.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      R 1 Reply Last reply
      3
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        You have to copy var (instead passing by reference to the lambda) since it goes out of scope in your first example.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        R 1 Reply Last reply
        2
        • Christian EhrlicherC Christian Ehrlicher

          You have to copy var (instead passing by reference to the lambda) since it goes out of scope in your first example.

          R Offline
          R Offline
          r3d9u11
          wrote on last edited by r3d9u11
          #3

          @Christian-Ehrlicher Yes, I did it in first example, too (as workaround).

          But if you have some huge data, you shouldn't pass it as a copy.
          If you can guarantee thread-safe mechanism, so lambda allows use references for it.

          However, I confused a bit why it does metter for Qt where was constant defined:

          static void calllambda(const qint64 var) // var defined at the head of function, has excepted behavior in QtConcurrency
          

          and

          const qint64 var = 123123123; // var defined inside body of function, works fine in QtConcurrency
          

          but it doesn't metter for pure C++, it has the same behavior in all cases.

          Looks like a bug.

          1 Reply Last reply
          0
          • Christian EhrlicherC Online
            Christian EhrlicherC Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @r3d9u11 said in Need advice with QtConcurrency & lambda expression:

            but it doesn't metter for pure C++

            This is a pure c++ problem...

            var is local inside calllambda() and gets destroyed when the function exits. Then later the lambda is called in another thread and accesses garbage.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            R 1 Reply Last reply
            3
            • Christian EhrlicherC Christian Ehrlicher

              @r3d9u11 said in Need advice with QtConcurrency & lambda expression:

              but it doesn't metter for pure C++

              This is a pure c++ problem...

              var is local inside calllambda() and gets destroyed when the function exits. Then later the lambda is called in another thread and accesses garbage.

              R Offline
              R Offline
              r3d9u11
              wrote on last edited by r3d9u11
              #5

              @Christian-Ehrlicher said in Need advice with QtConcurrency & lambda expression:

              var is local inside calllambda() and gets destroyed when the function exits

              Aha, sure, local variable will be destroyed before lambda function will try to get access from parallel thread.
              To test I can add QThread::msleep(10); at the end of calllambda function (after QtConcurrency::run).

              There is no problems in Qt or pure C++, the problem is in logic of example.

              It's clear now, thank you!

              1 Reply Last reply
              1

              • Login

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