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. Using QTcpSocket from multiple threads (Locking/Synchronous approach)
QtWS25 Last Chance

Using QTcpSocket from multiple threads (Locking/Synchronous approach)

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 5 Posters 696 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    nico88desmo
    wrote on last edited by
    #1

    Dear all,

    I'm developing a library to communicate to an hardware-device using TCP/IP protocol.
    I can't use asynchronous approach cause there might not be any QEventLoop on user side application.

    That hardware is able to manage maximum one TCP/IP connection per time; from user side, this device should be able to communicate from different threads (status, command, ecc...).

    My idea is to create a DeviceController class which let user application using that device; to handle different threads, this is the idea:

    1. For first connection, create a QTcpSocket and track which is its "creator" thread
    2. for the other threads, I'll create others QTcpSocket and I'll set them the socketDescriptor using setSocketDescriptor method

    In this way, I should be able to use QTcpSocket safely from different threads (clearly, cause socketDescriptor is shared among different thread, from user side a locking access is needed).
    I know isn't possible to use QTcpSocket from different threads, cause QTcpSocket is neither re-entrant not thread-safe. So the only way to share connection, is sharing its socketdescriptor.

    Is this a correct solution?

    Nicola

    SGaistS jeremy_kJ 2 Replies Last reply
    0
    • N nico88desmo

      @jeremy_k said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

      This begs further explanation. If the code can create a thread, why can't it create a QThread and use the event loop which that thread provides? I'm skeptical that the event loop provided by the QCoreApplication instance can't be used, but there are situations involving integrating as a plugin that can be painful.

      The idea to not use a QThread with its event loop is because I don't like so much the idea to use a signal/slot pattern just to read/write data on a socket; but if there isn't any other way, I think I haven't got any choice.

      @jeremy_k said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

      From the documentation forQAbstractSocket::setSocketDescriptor():

      Note: It is not possible to initialize two abstract sockets with the same native socket descriptor.

      That sentence raises my doubts.

      So, from what I understand:

      • a QTcpSocket instance is not shareable among different threads, even if its access is done using a mutual exclusion way
      • passing the same socketDescriptor to different QTcpSocket instances is not feasible.

      So, if I need to share a QTcpSocket on different threads (cause I can't use multiple connections to that device), the only way is moving that socket instance into a dedicated event-loop thread and use signal/slots/invokeMethod/QFuture pattern to read/write from that socket. Is it correct?

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

      @nico88desmo said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

      . Is it correct?

      Yes. Or better - simply use signals and slots.
      But as you don't like the basic Qt stuff - simply use the underlying socket stuff from the os.

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

      N 1 Reply Last reply
      1
      • N nico88desmo

        Dear all,

        I'm developing a library to communicate to an hardware-device using TCP/IP protocol.
        I can't use asynchronous approach cause there might not be any QEventLoop on user side application.

        That hardware is able to manage maximum one TCP/IP connection per time; from user side, this device should be able to communicate from different threads (status, command, ecc...).

        My idea is to create a DeviceController class which let user application using that device; to handle different threads, this is the idea:

        1. For first connection, create a QTcpSocket and track which is its "creator" thread
        2. for the other threads, I'll create others QTcpSocket and I'll set them the socketDescriptor using setSocketDescriptor method

        In this way, I should be able to use QTcpSocket safely from different threads (clearly, cause socketDescriptor is shared among different thread, from user side a locking access is needed).
        I know isn't possible to use QTcpSocket from different threads, cause QTcpSocket is neither re-entrant not thread-safe. So the only way to share connection, is sharing its socketdescriptor.

        Is this a correct solution?

        Nicola

        SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @nico88desmo Hi,

        Why not have your controller as only entry-point to write to the socket ?
        Your threads would communicate with your controller and would not need to know anything about that socket.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        N 1 Reply Last reply
        0
        • mrdebugM Offline
          mrdebugM Offline
          mrdebug
          wrote on last edited by
          #3

          Hi, when I have to manage remote tcp (or serial, it is the same) devices I normally use a synchronous approach.
          If a plant can have not so much devices (less than 100) I normally use a thread for each connection. If a plant can have thousands of device I normally use a thread that can manage more than one connection.
          To use a thread it is more simple when there is a complex state machine.
          In other words you can use a thread that can create one or more QTcpSocket objects and to manager it I suggest to use the non blocking methods.

          Need programmers to hire?
          www.labcsp.com
          www.denisgottardello.it
          GMT+1
          Skype: mrdebug

          1 Reply Last reply
          0
          • SGaistS SGaist

            @nico88desmo Hi,

            Why not have your controller as only entry-point to write to the socket ?
            Your threads would communicate with your controller and would not need to know anything about that socket.

            N Offline
            N Offline
            nico88desmo
            wrote on last edited by
            #4

            @SGaist said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

            @nico88desmo Hi,

            Why not have your controller as only entry-point to write to the socket ?
            Your threads would communicate with your controller and would not need to know anything about that socket.

            This is the idea: I'd like having that controller which uses the socket: from user side, the only visible things are common methods such as:

            • connect()
            • disconnect()
            • setup connection(..)

            @mrdebug said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

            Hi, when I have to manage remote tcp (or serial, it is the same) devices I normally use a synchronous approach.
            If a plant can have not so much devices (less than 100) I normally use a thread for each connection. If a plant can have thousands of device I normally use a thread that can manage more than one connection.
            To use a thread it is more simple when there is a complex state machine.
            In other words you can use a thread that can create one or more QTcpSocket objects and to manager it I suggest to use the non blocking methods.

            Yes I use a similar approach too: for devices that make multiple connection available, I follow this idea (single connection for each thread = neither concurrent problem, nor mutual access, etc).

            The problem for this device is that I can have only a single connection to it; this constraints me to share socket connection to multiple threads (but user doesn't know this, he "sees" just a controller).
            So, inside that controller, I'm going to manage this socket object; unfortunately I can't share QTcpSocket through different threads, even if it is protected using a mutex; I've tried this solution, but I have some undefined behaviour (sometimes some memory leakage, sometimes access violation): the only feasible way to share a QTcpSocket is creating a set of QTcpSockets, each of them having the same socketDescriptor.

            Unfortunately I haven't seen any deep article about how to use socketDescriptor, just this description

            1 Reply Last reply
            0
            • N nico88desmo

              Dear all,

              I'm developing a library to communicate to an hardware-device using TCP/IP protocol.
              I can't use asynchronous approach cause there might not be any QEventLoop on user side application.

              That hardware is able to manage maximum one TCP/IP connection per time; from user side, this device should be able to communicate from different threads (status, command, ecc...).

              My idea is to create a DeviceController class which let user application using that device; to handle different threads, this is the idea:

              1. For first connection, create a QTcpSocket and track which is its "creator" thread
              2. for the other threads, I'll create others QTcpSocket and I'll set them the socketDescriptor using setSocketDescriptor method

              In this way, I should be able to use QTcpSocket safely from different threads (clearly, cause socketDescriptor is shared among different thread, from user side a locking access is needed).
              I know isn't possible to use QTcpSocket from different threads, cause QTcpSocket is neither re-entrant not thread-safe. So the only way to share connection, is sharing its socketdescriptor.

              Is this a correct solution?

              Nicola

              jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by
              #5

              @nico88desmo said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

              I can't use asynchronous approach cause there might not be any QEventLoop on user side application.

              This begs further explanation. If the code can create a thread, why can't it create a QThread and use the event loop which that thread provides? I'm skeptical that the event loop provided by the QCoreApplication instance can't be used, but there are situations involving integrating as a plugin that can be painful.

              1. for the other threads, I'll create others QTcpSocket and I'll set them the socketDescriptor using setSocketDescriptor method

              From the documentation forQAbstractSocket::setSocketDescriptor():

              Note: It is not possible to initialize two abstract sockets with the same native socket descriptor.

              Asking a question about code? http://eel.is/iso-c++/testcase/

              N 1 Reply Last reply
              1
              • jeremy_kJ jeremy_k

                @nico88desmo said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                I can't use asynchronous approach cause there might not be any QEventLoop on user side application.

                This begs further explanation. If the code can create a thread, why can't it create a QThread and use the event loop which that thread provides? I'm skeptical that the event loop provided by the QCoreApplication instance can't be used, but there are situations involving integrating as a plugin that can be painful.

                1. for the other threads, I'll create others QTcpSocket and I'll set them the socketDescriptor using setSocketDescriptor method

                From the documentation forQAbstractSocket::setSocketDescriptor():

                Note: It is not possible to initialize two abstract sockets with the same native socket descriptor.

                N Offline
                N Offline
                nico88desmo
                wrote on last edited by nico88desmo
                #6

                @jeremy_k said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                This begs further explanation. If the code can create a thread, why can't it create a QThread and use the event loop which that thread provides? I'm skeptical that the event loop provided by the QCoreApplication instance can't be used, but there are situations involving integrating as a plugin that can be painful.

                The idea to not use a QThread with its event loop is because I don't like so much the idea to use a signal/slot pattern just to read/write data on a socket; but if there isn't any other way, I think I haven't got any choice.

                @jeremy_k said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                From the documentation forQAbstractSocket::setSocketDescriptor():

                Note: It is not possible to initialize two abstract sockets with the same native socket descriptor.

                That sentence raises my doubts.

                So, from what I understand:

                • a QTcpSocket instance is not shareable among different threads, even if its access is done using a mutual exclusion way
                • passing the same socketDescriptor to different QTcpSocket instances is not feasible.

                So, if I need to share a QTcpSocket on different threads (cause I can't use multiple connections to that device), the only way is moving that socket instance into a dedicated event-loop thread and use signal/slots/invokeMethod/QFuture pattern to read/write from that socket. Is it correct?

                Christian EhrlicherC 1 Reply Last reply
                0
                • N nico88desmo

                  @jeremy_k said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                  This begs further explanation. If the code can create a thread, why can't it create a QThread and use the event loop which that thread provides? I'm skeptical that the event loop provided by the QCoreApplication instance can't be used, but there are situations involving integrating as a plugin that can be painful.

                  The idea to not use a QThread with its event loop is because I don't like so much the idea to use a signal/slot pattern just to read/write data on a socket; but if there isn't any other way, I think I haven't got any choice.

                  @jeremy_k said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                  From the documentation forQAbstractSocket::setSocketDescriptor():

                  Note: It is not possible to initialize two abstract sockets with the same native socket descriptor.

                  That sentence raises my doubts.

                  So, from what I understand:

                  • a QTcpSocket instance is not shareable among different threads, even if its access is done using a mutual exclusion way
                  • passing the same socketDescriptor to different QTcpSocket instances is not feasible.

                  So, if I need to share a QTcpSocket on different threads (cause I can't use multiple connections to that device), the only way is moving that socket instance into a dedicated event-loop thread and use signal/slots/invokeMethod/QFuture pattern to read/write from that socket. Is it correct?

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

                  @nico88desmo said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                  . Is it correct?

                  Yes. Or better - simply use signals and slots.
                  But as you don't like the basic Qt stuff - simply use the underlying socket stuff from the os.

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

                  N 1 Reply Last reply
                  1
                  • Christian EhrlicherC Christian Ehrlicher

                    @nico88desmo said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                    . Is it correct?

                    Yes. Or better - simply use signals and slots.
                    But as you don't like the basic Qt stuff - simply use the underlying socket stuff from the os.

                    N Offline
                    N Offline
                    nico88desmo
                    wrote on last edited by
                    #8

                    @Christian-Ehrlicher said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                    @nico88desmo said in Using QTcpSocket from multiple threads (Locking/Synchronous approach):

                    . Is it correct?

                    Yes. Or better - simply use signals and slots.
                    But as you don't like the basic Qt stuff - simply use the underlying socket stuff from the os.

                    Between the two solutions, I think I'm going to signal/slot approach ;)

                    1 Reply Last reply
                    0
                    • N nico88desmo has marked this topic as solved on

                    • Login

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