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.
Forum Updated to NodeBB v4.3 + New Features

Question about QThread and how thread work in general.

Scheduled Pinned Locked Moved Solved C++ Gurus
32 Posts 9 Posters 8.4k Views 6 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.
  • F Factao
    20 Mar 2019, 00:46

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

    C Offline
    C Offline
    CP71
    wrote on 20 Mar 2019, 08:49 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
      20 Mar 2019, 00:46

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

      K Offline
      K Offline
      kshegunov
      Moderators
      wrote on 20 Mar 2019, 09:48 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 20 Mar 2019, 18:50
      2
      • K kshegunov
        20 Mar 2019, 09:48

        @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 20 Mar 2019, 18:50 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?

        K K 2 Replies Last reply 21 Mar 2019, 10:16
        1
        • K Online
          K Online
          Kent-Dorfman
          wrote on 20 Mar 2019, 21:19 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 20 Mar 2019, 23:44
          0
          • K Kent-Dorfman
            20 Mar 2019, 21:19

            @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 20 Mar 2019, 23:44 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.

            C 1 Reply Last reply 21 Mar 2019, 09:43
            2
            • F Factao
              20 Mar 2019, 23:44

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

              C Offline
              C Offline
              CP71
              wrote on 21 Mar 2019, 09:43 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
                20 Mar 2019, 18:50

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

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 21 Mar 2019, 10:16 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

                C 1 Reply Last reply 21 Mar 2019, 11:02
                2
                • K kshegunov
                  21 Mar 2019, 10:16

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

                  C Offline
                  C Offline
                  CP71
                  wrote on 21 Mar 2019, 11:02 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 1 Reply Last reply 21 Mar 2019, 11:07
                  0
                  • C CP71
                    21 Mar 2019, 11:02

                    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 Offline
                    J Offline
                    J.Hilk
                    Moderators
                    wrote on 21 Mar 2019, 11:07 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.

                    C 1 Reply Last reply 21 Mar 2019, 11:11
                    2
                    • J J.Hilk
                      21 Mar 2019, 11:07

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

                      C Offline
                      C Offline
                      CP71
                      wrote on 21 Mar 2019, 11:11 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
                      • F Offline
                        F Offline
                        Factao
                        wrote on 21 Mar 2019, 23:29 last edited by
                        #27

                        Well, thank you everyone, thank you. I think that we can conclude this topic. Once again, thank you.

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

                        I think I could learn from you ;)

                        If you need help on a subject that is more mechanical or mathematical, don't hesitate, I will be more than happy to help you back.

                        C 1 Reply Last reply 22 Mar 2019, 07:31
                        1
                        • F Factao
                          21 Mar 2019, 23:29

                          Well, thank you everyone, thank you. I think that we can conclude this topic. Once again, thank you.

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

                          I think I could learn from you ;)

                          If you need help on a subject that is more mechanical or mathematical, don't hesitate, I will be more than happy to help you back.

                          C Offline
                          C Offline
                          CP71
                          wrote on 22 Mar 2019, 07:31 last edited by
                          #28

                          @Factao
                          Sure, count on it.
                          Thanks

                          1 Reply Last reply
                          0
                          • F Factao
                            20 Mar 2019, 18:50

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

                            K Offline
                            K Offline
                            KroMignon
                            wrote on 22 Mar 2019, 08:28 last edited by
                            #29

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

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

                            Hi Factao, just give you a little hint abour QMutex usage, the easiest way to deal with QMutex, is to use QMutexLocker, to avoid having mutex lock when leaving function:

                            int class::returnSomething() const
                            {
                                QMutexLocker lock(&mutex);
                                Q_UNUSED(lock) // just to remove warnings
                                return m_something;
                            };
                            

                            At function begin, mutex will be locked, and when lock is distroyed (by living function) mutex will be released.
                            This will avoid having deadlocks!

                            But as writen in other comments, using Signals/Slots mechanisme to exhange information between object in different thread is the most easiest way. You don't have to deal with mutex. The disadvantage is that will have shadow copies of your data, so if there are big amonth of data, this could be a problem.

                            Hope this will help you

                            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                            K 1 Reply Last reply 22 Mar 2019, 11:41
                            5
                            • K KroMignon
                              22 Mar 2019, 08:28

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

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

                              Hi Factao, just give you a little hint abour QMutex usage, the easiest way to deal with QMutex, is to use QMutexLocker, to avoid having mutex lock when leaving function:

                              int class::returnSomething() const
                              {
                                  QMutexLocker lock(&mutex);
                                  Q_UNUSED(lock) // just to remove warnings
                                  return m_something;
                              };
                              

                              At function begin, mutex will be locked, and when lock is distroyed (by living function) mutex will be released.
                              This will avoid having deadlocks!

                              But as writen in other comments, using Signals/Slots mechanisme to exhange information between object in different thread is the most easiest way. You don't have to deal with mutex. The disadvantage is that will have shadow copies of your data, so if there are big amonth of data, this could be a problem.

                              Hope this will help you

                              K Offline
                              K Offline
                              kshegunov
                              Moderators
                              wrote on 22 Mar 2019, 11:41 last edited by kshegunov
                              #30

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

                              will have shadow copies of your data

                              For implicitly shared types (Qt types) - shallow copies, which may or may not, depending on the use, become deep copies.

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

                              Hi @kshegunov,
                              Is there difference using signals&slots or direct method between threads with different priority?

                              Priority has nothing to do with anything. The thread priority is a hint to the scheduler how large a time slot to dispense.

                              Read and abide by the Qt Code of Conduct

                              K 1 Reply Last reply 22 Mar 2019, 14:12
                              2
                              • K kshegunov
                                22 Mar 2019, 11:41

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

                                will have shadow copies of your data

                                For implicitly shared types (Qt types) - shallow copies, which may or may not, depending on the use, become deep copies.

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

                                Hi @kshegunov,
                                Is there difference using signals&slots or direct method between threads with different priority?

                                Priority has nothing to do with anything. The thread priority is a hint to the scheduler how large a time slot to dispense.

                                K Offline
                                K Offline
                                Konstantin Tokarev
                                wrote on 22 Mar 2019, 14:12 last edited by
                                #31

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

                                Priority has nothing to do with anything. The thread priority is a hint to the scheduler how large a time slot to dispense.

                                Actually, in some operating systems (e.g. in Linux via sched_setscheduler) it's possible to change scheduler for particular thread to real-time (in Linux SCHED_FIFO or SCHED_RR). Real-time thread have static priorities which has deeper effect on time slots than dynamic ("nice") priorities

                                (QThread::IdlePriority is internally implemented via SCHED_IDLE on Linux, other options use default scheduler with dynamic priorities)

                                K 1 Reply Last reply 22 Mar 2019, 14:46
                                0
                                • K Konstantin Tokarev
                                  22 Mar 2019, 14:12

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

                                  Priority has nothing to do with anything. The thread priority is a hint to the scheduler how large a time slot to dispense.

                                  Actually, in some operating systems (e.g. in Linux via sched_setscheduler) it's possible to change scheduler for particular thread to real-time (in Linux SCHED_FIFO or SCHED_RR). Real-time thread have static priorities which has deeper effect on time slots than dynamic ("nice") priorities

                                  (QThread::IdlePriority is internally implemented via SCHED_IDLE on Linux, other options use default scheduler with dynamic priorities)

                                  K Offline
                                  K Offline
                                  kshegunov
                                  Moderators
                                  wrote on 22 Mar 2019, 14:46 last edited by
                                  #32

                                  Perhaps, but I don't see an implication for the case of signal-slot connections vs direct synchronization ... at the end of the day the former still uses a mutex to serialize access to the queued events ...

                                  Read and abide by the Qt Code of Conduct

                                  1 Reply Last reply
                                  0

                                  26/32

                                  21 Mar 2019, 11:11

                                  • Login

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