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. Question about QThread and how thread work in general.
QtWS25 Last Chance

Question about QThread and how thread work in general.

Scheduled Pinned Locked Moved Solved C++ Gurus
32 Posts 9 Posters 8.0k 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.
  • Kent-DorfmanK Offline
    Kent-DorfmanK Offline
    Kent-Dorfman
    wrote on last edited by
    #7

    For simply sending data between the main GUI thread and a worker thread the signal/slot mechanism is the safer alternative, as it is well tested and simple to use. Unless there are near real-time requirements of syncronization then that's the route I'd recommend.

    1 Reply Last reply
    1
    • F Factao

      @CP71
      Hi,
      Basically, I have two class that inherits from QObject, one of them is on the main and the other is on a thread. They both contain a pointer to the other and used this pointer to read an change their values. I think it might be this direct synchronisation you are talking about.
      My question is: Could this method have default that could result in a crash or any other thing that may make the application having some unexpected feature?

      ps: Don't worry, your I'm not an english native neither and I perfectly understand what you are saying.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #8

      @Factao if you really want to pass objects/data/pointers between threads and allow them to modify/read the data, than you'll have too look into QMutex

      https://doc.qt.io/qt-5/qmutex.html


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      F 1 Reply Last reply
      1
      • Kent-DorfmanK Offline
        Kent-DorfmanK Offline
        Kent-Dorfman
        wrote on last edited by
        #9

        @J.Hilk said in Question about QThread and how thread work in general.:

        if you really want to pass objects/data/pointers between threads and allow them to modify/read the data, than you'll have too look into

        pass objects, or share objects? if the objects are shared then yes, the mutex/semaphore would be required, but if the objects are passed (copied) then signal/slot would be adequate, right?

        J.HilkJ 1 Reply Last reply
        0
        • Kent-DorfmanK Kent-Dorfman

          @J.Hilk said in Question about QThread and how thread work in general.:

          if you really want to pass objects/data/pointers between threads and allow them to modify/read the data, than you'll have too look into

          pass objects, or share objects? if the objects are shared then yes, the mutex/semaphore would be required, but if the objects are passed (copied) then signal/slot would be adequate, right?

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #10

          @Kent-Dorfman well yes, I wrote objects/data/pointers and meant to write objects/data - pointers ;-)


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          0
          • J.HilkJ J.Hilk

            @Factao if you really want to pass objects/data/pointers between threads and allow them to modify/read the data, than you'll have too look into QMutex

            https://doc.qt.io/qt-5/qmutex.html

            F Offline
            F Offline
            Factao
            wrote on last edited by
            #11

            @J.Hilk Interesting, but after looking QMutex, I have one quesition: If I'm locking a variable within a thread, may other thread "read" it? Within the docs, the following sentence does not specifiy that: "Then only one thread can modify number...". (after the example within the QMutex class). If I don't need to modify this value, then thread should not have any difficulties to read a variable that only one thread is modifying.

            @Kent-Dorfman Yes, I need a near real-time synchronisation, so I can't use too many signals or slots.

            1 Reply Last reply
            0
            • Kent-DorfmanK Offline
              Kent-DorfmanK Offline
              Kent-Dorfman
              wrote on last edited by
              #12

              @Factao said in Question about QThread and how thread work in general.:

              If I'm locking a variable within a thread, may other thread "read" it?

              Multithreaded reads are only consistent on atomic data items. IOW, ordinal variables that can be read or written with a single processor native instruction. You have no way of guaranteeing when a context switch will occur, so values of more complex variables are undefined unless you guard their access with a critical section lock (ie semaphore/mutex)

              F 1 Reply Last reply
              2
              • Kent-DorfmanK Kent-Dorfman

                @Factao said in Question about QThread and how thread work in general.:

                If I'm locking a variable within a thread, may other thread "read" it?

                Multithreaded reads are only consistent on atomic data items. IOW, ordinal variables that can be read or written with a single processor native instruction. You have no way of guaranteeing when a context switch will occur, so values of more complex variables are undefined unless you guard their access with a critical section lock (ie semaphore/mutex)

                F Offline
                F Offline
                Factao
                wrote on last edited by Factao
                #13

                @Kent-Dorfman I'm not really sure to understand your answer, so here is an incomplete example of what I'm trying to do:

                class A: public QObject
                {
                public:
                //constructor an destructor
                void methoda(int a);
                int geta() const; //return m_a
                B *m_B;//see below
                 private:
                int m_a;
                }
                class B: public QObject
                {
                public:
                //constructor an destructor
                void methodb(int b);
                int getb() const; //return m_b
                A *m_A;
                 private:
                int m_b;
                }
                 int main();
                {
                //everything is initialized
                B *BB= new *B();
                A  *AA= new *A();
                //somehow set BB->m_A=AA and AA->m_B=BB
                QThread thread(BB);
                thread.start();
                //two action that read the other class
                AA->methoda(AA->m_B->getb());
                BB->methodb(BB->m_A->geta());
                //do stuff...
                

                At no moment something is modified. Does that need mutex or not?

                kshegunovK 1 Reply Last reply
                0
                • F Factao

                  @Kent-Dorfman I'm not really sure to understand your answer, so here is an incomplete example of what I'm trying to do:

                  class A: public QObject
                  {
                  public:
                  //constructor an destructor
                  void methoda(int a);
                  int geta() const; //return m_a
                  B *m_B;//see below
                   private:
                  int m_a;
                  }
                  class B: public QObject
                  {
                  public:
                  //constructor an destructor
                  void methodb(int b);
                  int getb() const; //return m_b
                  A *m_A;
                   private:
                  int m_b;
                  }
                   int main();
                  {
                  //everything is initialized
                  B *BB= new *B();
                  A  *AA= new *A();
                  //somehow set BB->m_A=AA and AA->m_B=BB
                  QThread thread(BB);
                  thread.start();
                  //two action that read the other class
                  AA->methoda(AA->m_B->getb());
                  BB->methodb(BB->m_A->geta());
                  //do stuff...
                  

                  At no moment something is modified. Does that need mutex or not?

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by
                  #14

                  If you don't have experience with low-level threading primitives, then I kindly suggest you stick to signal-slot connections. The former can lead to difficult to diagnose errors that may not be trivial to fix. At least with the signal-slot mechanism you get serialization out of the box, which by the way is suitable for most practical cases.

                  Read and abide by the Qt Code of Conduct

                  F 1 Reply Last reply
                  4
                  • kshegunovK kshegunov

                    If you don't have experience with low-level threading primitives, then I kindly suggest you stick to signal-slot connections. The former can lead to difficult to diagnose errors that may not be trivial to fix. At least with the signal-slot mechanism you get serialization out of the box, which by the way is suitable for most practical cases.

                    F Offline
                    F Offline
                    Factao
                    wrote on last edited by
                    #15

                    @kshegunov Please, don't think that it is the first time that I encounter something that I'm not familiar with. If I would have stick to what I know in order to accomplish something, I wouldn't accomplished anything. If you are trying to tell me that what I'm asking can't be answered here because its too complicated for a simple post and you might need to wrote a book in order to do so, then tell it to me.

                    jsulmJ CP71C kshegunovK 3 Replies Last reply
                    0
                    • F Factao

                      @kshegunov Please, don't think that it is the first time that I encounter something that I'm not familiar with. If I would have stick to what I know in order to accomplish something, I wouldn't accomplished anything. If you are trying to tell me that what I'm asking can't be answered here because its too complicated for a simple post and you might need to wrote a book in order to do so, then tell it to me.

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

                      @Factao I think what @kshegunov tried to tell you is that in most cases signals/slots are enough and the right way in Qt to communicate between threads. Low level multi-threading is indeed a complex topic, but nobody here forbids you to learn it. But it is not really possible to explain it in a post in a forum. You should look for tutorials/books.
                      Regarding locking for read access see https://doc.qt.io/qt-5/qreadwritelock.html

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

                      1 Reply Last reply
                      3
                      • F Factao

                        @kshegunov Please, don't think that it is the first time that I encounter something that I'm not familiar with. If I would have stick to what I know in order to accomplish something, I wouldn't accomplished anything. If you are trying to tell me that what I'm asking can't be answered here because its too complicated for a simple post and you might need to wrote a book in order to do so, then tell it to me.

                        CP71C Offline
                        CP71C Offline
                        CP71
                        wrote on last edited by CP71
                        #17

                        @Factao
                        Hi @Factao,
                        well, as always I hope I’m being understood correctly due to my English ;)
                        I joined at forum about a year ago and I’ve been active only for some months, I think nobody knows somebody, at least, is true for most of us, so it is not easy knowing coding level of someone only by his/her post.
                        I have always found someone helps me, directly to me or indirectly about post of somebody else.
                        Sometimes the answers can seem obvious, only because who wrote don’t know your or my level of coding or Qt.
                        Please don't take it personally, at least I do this.

                        Having said that, let’s come back about synchronization of thread, if you don’t want to use signals and slots you must use some mechanisms to avoid a simultaneous access to a member of thread, normally I use QMutex, so what I say it is certainly true for QMutex, but I think it is same for the other mechanisms.

                        In both thead you must declare a Qmutex and you must call lock and unlock before access a member of class.

                        In your H:
                        QMutex myMutex.

                        In your cpp
                        void myClass::setMyIntValue(int newValue)
                        {
                        myMutex,lock();
                        mMyMemberInt = newValue;
                        myMutex,unlock();
                        }

                        Please pay attention, if 2 or more threads call setMyIntValue only the first will be executed, the others will waiting for unlock to be executed.
                        In Short lock of mutex blocks execution of next caller until unlock.

                        Regards
                        CP71

                        1 Reply Last reply
                        2
                        • F Factao

                          @kshegunov Please, don't think that it is the first time that I encounter something that I'm not familiar with. If I would have stick to what I know in order to accomplish something, I wouldn't accomplished anything. If you are trying to tell me that what I'm asking can't be answered here because its too complicated for a simple post and you might need to wrote a book in order to do so, then tell it to me.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by
                          #18

                          @jsulm said in Question about QThread and how thread work in general.:

                          I think what @kshegunov tried to tell you is that in most cases signals/slots are enough and the right way in Qt to communicate between threads

                          That's exactly right. This is what I meant. There's nothing wrong with low-level threading, but most of the time with Qt it's not necessary.

                          Read and abide by the Qt Code of Conduct

                          F 1 Reply Last reply
                          2
                          • kshegunovK kshegunov

                            @jsulm said in Question about QThread and how thread work in general.:

                            I think what @kshegunov tried to tell you is that in most cases signals/slots are enough and the right way in Qt to communicate between threads

                            That's exactly right. This is what I meant. There's nothing wrong with low-level threading, but most of the time with Qt it's not necessary.

                            F Offline
                            F Offline
                            Factao
                            wrote on last edited by Factao
                            #19

                            @kshegunov Then I didn't understand the meaning of your first intervention. I apoligize

                            @kshegunov and @jsulm . I'm using slots and signals in order to command the worker thread, but this last one, when not doing a specific task, is within a loop, constantly reading value from a servo and saving them. Since there is a lot of variable that change frequently, emitting a signal for every one of them might slow the application down, due to how signal/slot work.

                            @CP71 Thanks, this is the example that I was looking for. To summarize, I'm locking when a thread is using a function that use a specific value and nothing more. So making a specific and short function that only return or modify the value is a good way to avoid traffic while multiple thread are accessing the same thing.
                            edit: After trying it, now I see that there is an issue with the function other than void, I can't do:

                            int m_something;// private element of class
                            int class::returnSomething() const
                            {
                            mutex.lock()
                            return m_something;
                            mutex.unlock()
                            };
                            

                            If I'm doing that:

                            int class::returnSomething() const
                            {
                            mutex.lock();
                            int something(m_something);
                            mutex.unlock();
                            return something;
                            }
                            

                            Is this what we are trying to do here? From what I understand, our goal Is to prevent two thread to access the same data simultaneously, not the same function.

                            So, to be sure of getting it, here is a summarize of what I get out of this topic:
                            We need to lock data when a thread is accessing it to be sure that the data going to stay where it should be during the operation. If we don't do it, a thread from another core could possibly "steal" the data that we need and create a little problems in our program.

                            Is this approximately true? Or do I miss something?

                            kshegunovK KroMignonK 2 Replies Last reply
                            1
                            • Kent-DorfmanK Offline
                              Kent-DorfmanK Offline
                              Kent-Dorfman
                              wrote on last edited by Kent-Dorfman
                              #20

                              @Factao said in Question about QThread and how thread work in general.:

                              We need to lock data when a thread is accessing it to be sure that the data going to stay where it should be during the operation. If we don't do it, a thread from another core could possibly "steal" the data that we need and create a little problems in our program.

                              Steal the data isn't the correct terminology, but you are essentially correct. You shouldn't care about multiple siumulatneous reads. It's only when something is changing the data that locking becomes a concern.

                              And for what it's worth, your application is beginning to smell very much like something that is not really appropriate for high level Qt on a PC or real CPU. real-time functions should usually be delegated to micro-controllers running RTOS programs specifically designed to handle real-time IO and then send agregate info to a higher level computer program on a real CPU.

                              Of course you don't elaborate on whether this is a hobbyist level, academic/learning, or for work, project.

                              F 1 Reply Last reply
                              0
                              • Kent-DorfmanK Kent-Dorfman

                                @Factao said in Question about QThread and how thread work in general.:

                                We need to lock data when a thread is accessing it to be sure that the data going to stay where it should be during the operation. If we don't do it, a thread from another core could possibly "steal" the data that we need and create a little problems in our program.

                                Steal the data isn't the correct terminology, but you are essentially correct. You shouldn't care about multiple siumulatneous reads. It's only when something is changing the data that locking becomes a concern.

                                And for what it's worth, your application is beginning to smell very much like something that is not really appropriate for high level Qt on a PC or real CPU. real-time functions should usually be delegated to micro-controllers running RTOS programs specifically designed to handle real-time IO and then send agregate info to a higher level computer program on a real CPU.

                                Of course you don't elaborate on whether this is a hobbyist level, academic/learning, or for work, project.

                                F Offline
                                F Offline
                                Factao
                                wrote on last edited by Factao
                                #21

                                @Kent-Dorfman Your right, I did not precise what is my project, so here is for you:

                                I am trying to make a bio-mimetic (in apearance, at least) robotical arm, wich is requiring around 20 smart servo to operate the hand. I'm using a raspberry pi 3B+ to operate everything. Since every servo cost $50 usd, I'm planning to make a loop that verify every servo and emit an emergency signal if something is going wrong. I'm planning to also use this verification as a feedback that would update the virtual representation of the force and position of the member. Since I'm more a guy that just get admitted in mechanical engineering that someone with a great knowledge of electronics, I'm planning to stick on the raspberry pi until I got some result out of this, but perhaps I will used a dedicated micro-controller for the communication and this loop. However, I'm planning to completed my personal exploration of c/c++ before doing so.

                                CP71C 1 Reply Last reply
                                2
                                • F Factao

                                  @Kent-Dorfman Your right, I did not precise what is my project, so here is for you:

                                  I am trying to make a bio-mimetic (in apearance, at least) robotical arm, wich is requiring around 20 smart servo to operate the hand. I'm using a raspberry pi 3B+ to operate everything. Since every servo cost $50 usd, I'm planning to make a loop that verify every servo and emit an emergency signal if something is going wrong. I'm planning to also use this verification as a feedback that would update the virtual representation of the force and position of the member. Since I'm more a guy that just get admitted in mechanical engineering that someone with a great knowledge of electronics, I'm planning to stick on the raspberry pi until I got some result out of this, but perhaps I will used a dedicated micro-controller for the communication and this loop. However, I'm planning to completed my personal exploration of c/c++ before doing so.

                                  CP71C Offline
                                  CP71C Offline
                                  CP71
                                  wrote on last edited by
                                  #22

                                  Hi,
                                  @Factao wow! very beautiful project.
                                  I think I could learn from you ;)

                                  Technically @Kent-Dorfman is right, You shouldn't care about multiple simultaneous reads because changes can become a problem.

                                  Anyway, when a function, that uses variables member, starts I prefer, if is possible, copying members (Note: only variables that can be changed by external class, for example via setXXXX functions) and I do this under lock and unlock.
                                  That's because I normally want to have a constant instant photo for all during of function.
                                  To avoid deadlock, if is possible, I prefer using QMutex with moderation and, always if is possible, only for changing and reading variables. Always to avoid deadlock I use QMutex to protect all body function very rarely. This is how I use QMutex, but doesn’t mean is right way, is right for me.

                                  Qt offers other classes for thread synchronization, for these I suggest you to read the manual.

                                  Regards
                                  Paolo

                                  1 Reply Last reply
                                  0
                                  • F Factao

                                    @kshegunov Then I didn't understand the meaning of your first intervention. I apoligize

                                    @kshegunov and @jsulm . I'm using slots and signals in order to command the worker thread, but this last one, when not doing a specific task, is within a loop, constantly reading value from a servo and saving them. Since there is a lot of variable that change frequently, emitting a signal for every one of them might slow the application down, due to how signal/slot work.

                                    @CP71 Thanks, this is the example that I was looking for. To summarize, I'm locking when a thread is using a function that use a specific value and nothing more. So making a specific and short function that only return or modify the value is a good way to avoid traffic while multiple thread are accessing the same thing.
                                    edit: After trying it, now I see that there is an issue with the function other than void, I can't do:

                                    int m_something;// private element of class
                                    int class::returnSomething() const
                                    {
                                    mutex.lock()
                                    return m_something;
                                    mutex.unlock()
                                    };
                                    

                                    If I'm doing that:

                                    int class::returnSomething() const
                                    {
                                    mutex.lock();
                                    int something(m_something);
                                    mutex.unlock();
                                    return something;
                                    }
                                    

                                    Is this what we are trying to do here? From what I understand, our goal Is to prevent two thread to access the same data simultaneously, not the same function.

                                    So, to be sure of getting it, here is a summarize of what I get out of this topic:
                                    We need to lock data when a thread is accessing it to be sure that the data going to stay where it should be during the operation. If we don't do it, a thread from another core could possibly "steal" the data that we need and create a little problems in our program.

                                    Is this approximately true? Or do I miss something?

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by
                                    #23

                                    @Factao said in Question about QThread and how thread work in general.:

                                    I'm using slots and signals in order to command the worker thread, but this last one, when not doing a specific task, is within a loop, constantly reading value from a servo and saving them. Since there is a lot of variable that change frequently, emitting a signal for every one of them might slow the application down, due to how signal/slot work.

                                    The signal-slot connections work very similarly to how you'd serialize access with a mutex, as a matter of fact they do exactly that - serialize access to the event loop through a mutex. So unless you can prove that emission and handling of signals is a bottleneck, that concern is moot. The big advantage, however, is that thread access is defined strictly and clearly for each QObject involved, so it makes for convenient and fast coding.

                                    Read and abide by the Qt Code of Conduct

                                    CP71C 1 Reply Last reply
                                    2
                                    • kshegunovK kshegunov

                                      @Factao said in Question about QThread and how thread work in general.:

                                      I'm using slots and signals in order to command the worker thread, but this last one, when not doing a specific task, is within a loop, constantly reading value from a servo and saving them. Since there is a lot of variable that change frequently, emitting a signal for every one of them might slow the application down, due to how signal/slot work.

                                      The signal-slot connections work very similarly to how you'd serialize access with a mutex, as a matter of fact they do exactly that - serialize access to the event loop through a mutex. So unless you can prove that emission and handling of signals is a bottleneck, that concern is moot. The big advantage, however, is that thread access is defined strictly and clearly for each QObject involved, so it makes for convenient and fast coding.

                                      CP71C Offline
                                      CP71C Offline
                                      CP71
                                      wrote on last edited by CP71
                                      #24

                                      Hi @kshegunov,
                                      I'm Qt developer only for few years, so I’m quite newbie ;)
                                      Is there difference using signals&slots or direct method between threads with different priority?
                                      I think yes but I’m not sure.
                                      Thanks

                                      J.HilkJ 1 Reply Last reply
                                      0
                                      • CP71C CP71

                                        Hi @kshegunov,
                                        I'm Qt developer only for few years, so I’m quite newbie ;)
                                        Is there difference using signals&slots or direct method between threads with different priority?
                                        I think yes but I’m not sure.
                                        Thanks

                                        J.HilkJ Offline
                                        J.HilkJ Offline
                                        J.Hilk
                                        Moderators
                                        wrote on last edited by
                                        #25

                                        @CP71 the main difference is, that your signal argument, if it is a struct or class, needs to have a copy constructor.

                                        Where as with direct mutex lock, you simply lock the data block, access it and unlock it.


                                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                        Q: What's that?
                                        A: It's blue light.
                                        Q: What does it do?
                                        A: It turns blue.

                                        CP71C 1 Reply Last reply
                                        2
                                        • J.HilkJ J.Hilk

                                          @CP71 the main difference is, that your signal argument, if it is a struct or class, needs to have a copy constructor.

                                          Where as with direct mutex lock, you simply lock the data block, access it and unlock it.

                                          CP71C Offline
                                          CP71C Offline
                                          CP71
                                          wrote on last edited by CP71
                                          #26

                                          @J.Hilk
                                          Thank you,
                                          yes this I know, my question was incomplete, sorry.
                                          but I’m thinking about response time.

                                          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