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. How to share data between threads using QThread
Forum Updated to NodeBB v4.3 + New Features

How to share data between threads using QThread

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 3 Posters 912 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.
  • N Offline
    N Offline
    n34rt
    wrote on last edited by
    #1

    I'm trying to learn how to share data between threads using QThread.

    In my code below
    when I try to print the value of worker_str sometimes i get an exception in the file qdebug.cpp:

    Exception thrown: read access violation.
    **p** was 0x111011101110111.
    

    and sometimes it prints worker_str as "".

    What I'm doing wrong? also, I should call thread->quit(); whenever I don't need that thread running anymore?


    #include "worker.h"
    
    App::App(QWidget *parent)
        : QMainWindow(parent)
    {
        ui.setupUi(this);
    
    
        QThread* thread = new QThread();
        Worker* worker = new Worker();
        worker->moveToThread(thread);
    
        QString str = "hello world";
    
        connect(thread, &QThread::started, worker, [worker, str]
        {
            worker->test(str);
        });
    
        connect(worker, &Worker::finished, thread, [worker, thread]
        {
            qDebug() << "worker_str: " <<  worker->worker_str;
    
            thread->quit();
        });    
    
        connect( worker, &Worker::finished, worker, &Worker::deleteLater);
        connect( thread, &QThread::finished, thread, &QThread::deleteLater);
        thread->start();
    }
    

    //worker.h
    class Worker : public QObject {
        Q_OBJECT
    public:
        Worker() {};
        ~Worker() {};
    
        QString worker_str;
    
    public slots:
        void test(QString str)
        {
            worker_str = str;
            qDebug() << "WORKER: str: " << str;
            emit finished();
        };
    
    signals:
        void finished();
    
    };
    
    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Your Worker object is already gone when you try to access it in your slot. You can see this when using a debugger and setting a breakpoint in the lambda and the dtor of Worker or use a memory checker tool like e.g. valgrind.

      class Worker : public QObject
      {
        Q_OBJECT
      public:
          ~Worker()
          {
            qWarning() << "DTOR" << this;
          }
          void test(QString str)
          {
              worker_str = str;
              qDebug() << "WORKER: str: " << str << this;
              emit finished();
          }
          QString worker_str;
      signals:
          void finished();
      };
      
      class App : public QMainWindow
      {
        Q_OBJECT
      public:
        App(QWidget *parent = nullptr) : QMainWindow(parent)
        {
          QThread* thread = new QThread();
          Worker* worker = new Worker();
          worker->moveToThread(thread);
      
          QString str = "hello world";
          connect(thread, &QThread::started, worker, [worker, str]
          {
              worker->test(str);
          });
          connect(worker, &Worker::finished, thread, [worker, thread]
          {
              qWarning() << "worker_str: " <<  worker->worker_str;
              thread->quit();
          });
          connect(worker, &Worker::finished, worker, &Worker::deleteLater);
          connect(thread, &QThread::finished, thread, &QThread::deleteLater);
          connect(thread, &QThread::finished, thread, &QCoreApplication::quit);
          thread->start();
        }
      };
      
      int main(int argc, char *argv[])
      {
        QApplication a(argc, argv);
        App app;
        return a.exec();
      }
      
      #include "main.moc"
      

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

      N 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        Your Worker object is already gone when you try to access it in your slot. You can see this when using a debugger and setting a breakpoint in the lambda and the dtor of Worker or use a memory checker tool like e.g. valgrind.

        class Worker : public QObject
        {
          Q_OBJECT
        public:
            ~Worker()
            {
              qWarning() << "DTOR" << this;
            }
            void test(QString str)
            {
                worker_str = str;
                qDebug() << "WORKER: str: " << str << this;
                emit finished();
            }
            QString worker_str;
        signals:
            void finished();
        };
        
        class App : public QMainWindow
        {
          Q_OBJECT
        public:
          App(QWidget *parent = nullptr) : QMainWindow(parent)
          {
            QThread* thread = new QThread();
            Worker* worker = new Worker();
            worker->moveToThread(thread);
        
            QString str = "hello world";
            connect(thread, &QThread::started, worker, [worker, str]
            {
                worker->test(str);
            });
            connect(worker, &Worker::finished, thread, [worker, thread]
            {
                qWarning() << "worker_str: " <<  worker->worker_str;
                thread->quit();
            });
            connect(worker, &Worker::finished, worker, &Worker::deleteLater);
            connect(thread, &QThread::finished, thread, &QThread::deleteLater);
            connect(thread, &QThread::finished, thread, &QCoreApplication::quit);
            thread->start();
          }
        };
        
        int main(int argc, char *argv[])
        {
          QApplication a(argc, argv);
          App app;
          return a.exec();
        }
        
        #include "main.moc"
        
        N Offline
        N Offline
        n34rt
        wrote on last edited by
        #3

        @Christian-Ehrlicher I get the same exception when trying your code

        Your Worker object is already gone when you try to access it in your slot.

        Could help pointing the proper way to read it then?

        Christian EhrlicherC 1 Reply Last reply
        0
        • N n34rt

          @Christian-Ehrlicher I get the same exception when trying your code

          Your Worker object is already gone when you try to access it in your slot.

          Could help pointing the proper way to read it then?

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @n34rt said in How to share data between threads using QThread:

          Could help pointing the proper way to read it then?

          Either pass the value poer signal/slot out of the thread or don't delete the worker in an own connect() but in the readout function.

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

          N 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            @n34rt said in How to share data between threads using QThread:

            Could help pointing the proper way to read it then?

            Either pass the value poer signal/slot out of the thread or don't delete the worker in an own connect() but in the readout function.

            N Offline
            N Offline
            n34rt
            wrote on last edited by n34rt
            #5

            @Christian-Ehrlicher

            or don't delete the worker in an own connect() but in the readout function.

            connect(worker, &Worker::finished, thread, [worker, thread]
            {
            
                qWarning() << "worker_str: " <<  worker->worker_str;
                thread->quit();
                thread->deleteLater();
                worker->deleteLater();
                connect(thread, &QThread::finished, thread, &QCoreApplication::quit);
            });
            

            like this?

            Is this line really necessary?

            connect(thread, &QThread::finished, thread, &QCoreApplication::quit);
            

            I mean, do i need to call QCoreApplication::quit for that thread?

            Christian EhrlicherC 1 Reply Last reply
            0
            • N n34rt

              @Christian-Ehrlicher

              or don't delete the worker in an own connect() but in the readout function.

              connect(worker, &Worker::finished, thread, [worker, thread]
              {
              
                  qWarning() << "worker_str: " <<  worker->worker_str;
                  thread->quit();
                  thread->deleteLater();
                  worker->deleteLater();
                  connect(thread, &QThread::finished, thread, &QCoreApplication::quit);
              });
              

              like this?

              Is this line really necessary?

              connect(thread, &QThread::finished, thread, &QCoreApplication::quit);
              

              I mean, do i need to call QCoreApplication::quit for that thread?

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @n34rt said in How to share data between threads using QThread:

              I mean, do i need to call QCoreApplication::quit for that thread?

              It's needed to properly end my testcase.

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

              N 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @n34rt said in How to share data between threads using QThread:

                I mean, do i need to call QCoreApplication::quit for that thread?

                It's needed to properly end my testcase.

                N Offline
                N Offline
                n34rt
                wrote on last edited by n34rt
                #7

                @Christian-Ehrlicher I'm asking if I do need to call it whenever I start a thread and don't need it anymore

                Christian EhrlicherC 1 Reply Last reply
                0
                • N n34rt

                  @Christian-Ehrlicher I'm asking if I do need to call it whenever I start a thread and don't need it anymore

                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @n34rt said in How to share data between threads using QThread:

                  I'm asking if I do need to call it whenever I start a thread and don't need it anymore

                  If you want to quit your application after your thread finished yes - but I doubt so.

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

                  N 1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    @n34rt said in How to share data between threads using QThread:

                    I'm asking if I do need to call it whenever I start a thread and don't need it anymore

                    If you want to quit your application after your thread finished yes - but I doubt so.

                    N Offline
                    N Offline
                    n34rt
                    wrote on last edited by
                    #9

                    @Christian-Ehrlicher I see thank you, sorry im a newbie about threading

                    Either pass the value poer signal/slot out of the thread

                    Could you point how is it?

                    jsulmJ 1 Reply Last reply
                    0
                    • N n34rt

                      @Christian-Ehrlicher I see thank you, sorry im a newbie about threading

                      Either pass the value poer signal/slot out of the thread

                      Could you point how is it?

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @n34rt said in How to share data between threads using QThread:

                      Could you point how is it?

                      Create a signal with a parameter of the type you want to pass and then a slot with same parameter type. Connect the signal and slot. Each time you want to pass the parameter emit the signal and give it the parameter.

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      2

                      • Login

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