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. Connecting several readyRead() signals to one slot (QSerialPort)

Connecting several readyRead() signals to one slot (QSerialPort)

Scheduled Pinned Locked Moved Solved General and Desktop
signals & slotsqserialport
19 Posts 5 Posters 3.9k 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.
  • S Offline
    S Offline
    smnsmn
    wrote on last edited by smnsmn
    #1

    Hello everyone,
    I'm writing a program that uses QSerialPort to exchange data. I had connected readyRead() signals from 3 QSerialPort objects to one slot called readComData() for convenience. However, now I'm wondering whether my code works correctly or not.
    My code runs in a single thread. If any data comes from serial ports simultaneously and readyRead() emits from these serial ports, will these signals be queued somehow? If they're queued somehow (I suppose so), will my slot be allowed to finish executing its code before this slot will be invoked by next signal in a queue or my slot will just be reentered each time the readyRead() signal emits from next QSerialPort object?
    I've done extensive Google search before posting, but failed to find any answers.

    jsulmJ 1 Reply Last reply
    0
    • S smnsmn

      Hello everyone,
      I'm writing a program that uses QSerialPort to exchange data. I had connected readyRead() signals from 3 QSerialPort objects to one slot called readComData() for convenience. However, now I'm wondering whether my code works correctly or not.
      My code runs in a single thread. If any data comes from serial ports simultaneously and readyRead() emits from these serial ports, will these signals be queued somehow? If they're queued somehow (I suppose so), will my slot be allowed to finish executing its code before this slot will be invoked by next signal in a queue or my slot will just be reentered each time the readyRead() signal emits from next QSerialPort object?
      I've done extensive Google search before posting, but failed to find any answers.

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

      @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

      will it be queued somehow

      yes, QueuedConnection is default when connecting signals/slots between different threads.

      "will my slot be allowed to finish executing its code before it will be invoked by next signal" - yes.

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

      S 1 Reply Last reply
      0
      • jsulmJ jsulm

        @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

        will it be queued somehow

        yes, QueuedConnection is default when connecting signals/slots between different threads.

        "will my slot be allowed to finish executing its code before it will be invoked by next signal" - yes.

        S Offline
        S Offline
        smnsmn
        wrote on last edited by smnsmn
        #3

        @jsulm

        My code runs in a single thread

        Sorry if I fail to use appropriate markup, I'm writing from my cell phone.

        jsulmJ J.HilkJ 2 Replies Last reply
        0
        • S smnsmn

          @jsulm

          My code runs in a single thread

          Sorry if I fail to use appropriate markup, I'm writing from my cell phone.

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

          @smnsmn Within same thread slots are simply called immediately when signal is emitted. That means: as long as a slot is executed no other slots will be called as the event loop is blocked. When the currently executed slot is finished event loop will pick next slot from the queue (if there is any).

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

          S 1 Reply Last reply
          0
          • S smnsmn

            @jsulm

            My code runs in a single thread

            Sorry if I fail to use appropriate markup, I'm writing from my cell phone.

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

            @smnsmn

            your code will be fine, as long as you do not do any of the following inside your readComData function

            • call the processEvent() function
            • create and execute a QEventLoop
            • Open a modal QDialog/QMessagebox

            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.

            JonBJ 1 Reply Last reply
            0
            • jsulmJ jsulm

              @smnsmn Within same thread slots are simply called immediately when signal is emitted. That means: as long as a slot is executed no other slots will be called as the event loop is blocked. When the currently executed slot is finished event loop will pick next slot from the queue (if there is any).

              S Offline
              S Offline
              smnsmn
              wrote on last edited by smnsmn
              #6

              @jsulm
              Please correct me if I'm wrong, but it seems to me that your answer conflicts with Qt Documentation (taken from article "Syncronizing Threads):

              To place an invocation in an event loop, make a queued signal-slot connection. Whenever the signal is emitted, its arguments will be recorded by the event system. The thread that the signal receiver lives in will then run the slot. Alternatively, call QMetaObject::invokeMethod() to achieve the same effect without signals. In both cases, a queued connection must be used because a direct connection bypasses the event system and runs the method immediately in the current thread.

              Specifically this statement:

              In both cases, a queued connection must be used because a direct connection bypasses the event system and runs the method immediately in the current thread.

              jsulmJ 1 Reply Last reply
              0
              • S smnsmn

                @jsulm
                Please correct me if I'm wrong, but it seems to me that your answer conflicts with Qt Documentation (taken from article "Syncronizing Threads):

                To place an invocation in an event loop, make a queued signal-slot connection. Whenever the signal is emitted, its arguments will be recorded by the event system. The thread that the signal receiver lives in will then run the slot. Alternatively, call QMetaObject::invokeMethod() to achieve the same effect without signals. In both cases, a queued connection must be used because a direct connection bypasses the event system and runs the method immediately in the current thread.

                Specifically this statement:

                In both cases, a queued connection must be used because a direct connection bypasses the event system and runs the method immediately in the current thread.

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

                @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

                but it seems to me that your answer conflicts with Qt Documenation

                In what way? That text from documentation explains signals/slots between DIFFERENT threads (queued connection).
                If thread A emits a signal, the slot in thread B will be executed inside thread B.
                But you said you're only using one thread, in this case you don't have to worry at all and what I said before applies.

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

                S 1 Reply Last reply
                1
                • jsulmJ jsulm

                  @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

                  but it seems to me that your answer conflicts with Qt Documenation

                  In what way? That text from documentation explains signals/slots between DIFFERENT threads (queued connection).
                  If thread A emits a signal, the slot in thread B will be executed inside thread B.
                  But you said you're only using one thread, in this case you don't have to worry at all and what I said before applies.

                  S Offline
                  S Offline
                  smnsmn
                  wrote on last edited by smnsmn
                  #8

                  @jsulm
                  Ok, that's how I understand it now (again, please correct me if I'm wrong):

                  1. In a single-threaded program the slots connected to emitted signals are executed immediately, whatever the Qt::ConnectionType is.
                  2. If it happens that signals are emitted simultaneously, they are written in a thread event queue and corresponding slots are processed one after another (the slot is invoked right after another slot (or the same slot) has finished its execution caused by previous signal from the thread event queue).

                  Am I right?

                  jsulmJ 1 Reply Last reply
                  0
                  • S smnsmn

                    @jsulm
                    Ok, that's how I understand it now (again, please correct me if I'm wrong):

                    1. In a single-threaded program the slots connected to emitted signals are executed immediately, whatever the Qt::ConnectionType is.
                    2. If it happens that signals are emitted simultaneously, they are written in a thread event queue and corresponding slots are processed one after another (the slot is invoked right after another slot (or the same slot) has finished its execution caused by previous signal from the thread event queue).

                    Am I right?

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

                    @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

                    Am I right?

                    Not really. In a single thread app slots cannot be emitted simultaneously, because there is only one thread. So, when a signal is emitted all connected slots are executed one after the other (in the same order they were connected to the signal).

                    void MyClass::myMethod()
                    {
                    ...
                    emit signal1(); // Here all slots connected to signal1() will be executed
                    ...
                    emit signal2(); // Here all slots connected to signal2() will be executed
                    }
                    

                    It is actually the same as if you would call the slots directly instead of emitting the signal:

                    
                    void MyClass::myMethod()
                    {
                    ...
                    slot11();
                    slot12()
                    slot1n();
                    ...
                    
                    slot21();
                    slot22()
                    slot2n();
                    }
                    

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

                    S 1 Reply Last reply
                    1
                    • jsulmJ jsulm

                      @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

                      Am I right?

                      Not really. In a single thread app slots cannot be emitted simultaneously, because there is only one thread. So, when a signal is emitted all connected slots are executed one after the other (in the same order they were connected to the signal).

                      void MyClass::myMethod()
                      {
                      ...
                      emit signal1(); // Here all slots connected to signal1() will be executed
                      ...
                      emit signal2(); // Here all slots connected to signal2() will be executed
                      }
                      

                      It is actually the same as if you would call the slots directly instead of emitting the signal:

                      
                      void MyClass::myMethod()
                      {
                      ...
                      slot11();
                      slot12()
                      slot1n();
                      ...
                      
                      slot21();
                      slot22()
                      slot2n();
                      }
                      
                      S Offline
                      S Offline
                      smnsmn
                      wrote on last edited by smnsmn
                      #10

                      @jsulm

                      Okay, here's that part of the code to make things clear:

                      connect(&(comPorts.com[0]), SIGNAL( readyRead() ), this, SLOT( readComData() ));
                      connect(&(comPorts.com[1]), SIGNAL( readyRead() ), this, SLOT( readComData() ));
                      connect(&(comPorts.com[2]), SIGNAL( readyRead() ), this, SLOT( readComData() ));
                      
                      1. If e.g. two of these serial ports receive some data at one time, in which order do they emit readyRead()? Will the signals be put in a thread event queue?
                      2. Do I understand correctly that readComData() slot will be invoked exactly two times, each time after the slot has finished its execution caused by previous signal (from the thread event queue?)?
                      JonBJ 1 Reply Last reply
                      0
                      • S smnsmn

                        @jsulm

                        Okay, here's that part of the code to make things clear:

                        connect(&(comPorts.com[0]), SIGNAL( readyRead() ), this, SLOT( readComData() ));
                        connect(&(comPorts.com[1]), SIGNAL( readyRead() ), this, SLOT( readComData() ));
                        connect(&(comPorts.com[2]), SIGNAL( readyRead() ), this, SLOT( readComData() ));
                        
                        1. If e.g. two of these serial ports receive some data at one time, in which order do they emit readyRead()? Will the signals be put in a thread event queue?
                        2. Do I understand correctly that readComData() slot will be invoked exactly two times, each time after the slot has finished its execution caused by previous signal (from the thread event queue?)?
                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #11

                        @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

                        If e.g. two of these serial ports receive some data at one time

                        There is not really a "simultaneously receive at one time", computers don't do that. You can be quite sure that the order would be undefined, in the sense that you cannot know/rely on which one would be seen first and emit its signal. If it makes any difference to you, readyRead()'s this will tell you which comport has received.

                        I don't understand about "readComData() slot will be invoked exactly two times". It should be invoked once per comport per data received (provided you extract the data arrived, you don't get another readyread on a device till you've done that).

                        S 1 Reply Last reply
                        2
                        • JonBJ JonB

                          @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

                          If e.g. two of these serial ports receive some data at one time

                          There is not really a "simultaneously receive at one time", computers don't do that. You can be quite sure that the order would be undefined, in the sense that you cannot know/rely on which one would be seen first and emit its signal. If it makes any difference to you, readyRead()'s this will tell you which comport has received.

                          I don't understand about "readComData() slot will be invoked exactly two times". It should be invoked once per comport per data received (provided you extract the data arrived, you don't get another readyread on a device till you've done that).

                          S Offline
                          S Offline
                          smnsmn
                          wrote on last edited by smnsmn
                          #12

                          @JonB

                          I don't understand about "readComData() slot will be invoked exactly two times".

                          Actually, I wanted to be sure that slot readComData() will be invoked by com ports in some succession and there would be no reentrance in the slot when there are readyRead() signals from each of the port at one time.

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

                            @smnsmn

                            your code will be fine, as long as you do not do any of the following inside your readComData function

                            • call the processEvent() function
                            • create and execute a QEventLoop
                            • Open a modal QDialog/QMessagebox
                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #13

                            @smnsmn
                            Earlier:
                            @J.Hilk said in Connecting several readyRead() signals to one slot (QSerialPort):

                            @smnsmn

                            your code will be fine, as long as you do not do any of the following inside your readComData function

                            • call the processEvent() function
                            • create and execute a QEventLoop
                            • Open a modal QDialog/QMessagebox

                            So long as your readComData() does not do any of these it will not get re-entered. Qt will pick up some "random" comport among those with data, raise the signal on that comport, and call your readComData(). Until your readComPort() returns, Qt will not be raising any more signals or calling your readComData() again. Only once that has returned will you get a new call, on the same or a different comport. But there is no knowing what order the signals will be raised from your comports if multiple ones have data.

                            1 Reply Last reply
                            2
                            • J.HilkJ Offline
                              J.HilkJ Offline
                              J.Hilk
                              Moderators
                              wrote on last edited by
                              #14

                              @smnsmn
                              I want to raise an additional point, because I think you're not aware of this

                              Just because the readyRead signal is emitted, does not mean that all data has already arrived at your serialPort.
                              It just means that since the last event loop cycle some data arrived at your port. You have to manage/check if enough/all data arrived, that will be almost impossible if multiple classes access the serial port on their own. You would have to make a manager class to handle that.


                              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.

                              S 1 Reply Last reply
                              3
                              • S Offline
                                S Offline
                                smnsmn
                                wrote on last edited by
                                #15

                                Thanks everyone for your time and patience.
                                Just one last question, I'm not sure whether it applies to Qt:
                                In which moment of time does the data from input buffer of serial port get erased?

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

                                  @smnsmn
                                  I want to raise an additional point, because I think you're not aware of this

                                  Just because the readyRead signal is emitted, does not mean that all data has already arrived at your serialPort.
                                  It just means that since the last event loop cycle some data arrived at your port. You have to manage/check if enough/all data arrived, that will be almost impossible if multiple classes access the serial port on their own. You would have to make a manager class to handle that.

                                  S Offline
                                  S Offline
                                  smnsmn
                                  wrote on last edited by smnsmn
                                  #16

                                  @J.Hilk
                                  Thank you for the answer.
                                  I am aware of that, but since only one class (and its instance) has access to these serial ports and I need to receive just 1 byte of data, it seems to me that what you're talking about isn't the case here.

                                  1 Reply Last reply
                                  0
                                  • S Offline
                                    S Offline
                                    smnsmn
                                    wrote on last edited by smnsmn
                                    #17

                                    I would also like to clarify one question.
                                    @jsulm said

                                    Within same thread slots are simply called immediately when signal is emitted.

                                    Qt Docs state the following:

                                    Qt::QueuedConnection
                                    The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.

                                    Can signal thread == receiver thread?

                                    jsulmJ 1 Reply Last reply
                                    0
                                    • A Offline
                                      A Offline
                                      Astrinus
                                      wrote on last edited by
                                      #18

                                      Sure. It is also very useful for faking recursion.

                                      1 Reply Last reply
                                      0
                                      • S smnsmn

                                        I would also like to clarify one question.
                                        @jsulm said

                                        Within same thread slots are simply called immediately when signal is emitted.

                                        Qt Docs state the following:

                                        Qt::QueuedConnection
                                        The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.

                                        Can signal thread == receiver thread?

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

                                        @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):

                                        Qt::QueuedConnection
                                        The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.

                                        This is for queued connections which are not used by default for signals/slots in same thread. You really need to differentiate between connections in same thread and such between different threads.

                                        "Can signal thread == receiver thread?" - sure, it is like this most of the time. Only if you use more than one thread you can have signals and slots in different threads. For signals and slots in same thread queued connection is NOT used, unless you tell Qt to do so (last parameter in connect() call).

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

                                        1 Reply Last reply
                                        3

                                        • Login

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