Page 1 of 2 12 LastLast
Results 1 to 20 of 22

Thread: QTCP Socket Server and threads

  1. #1
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default QTCP Socket Server and threads

    Hi All,

    I have an application that generates/obtain information information in the background, a pushed (signal) to a GUI and to a server class(inherits from QTCServer) which has the array of sockets(inherits from QTCPSocket)

    The GUI live in the main thread.
    The Server lives in working thread1 (everything is guard using mutex)
    The Generation/acquiring information is in working thread2.

    So the problem is i a deadlock.

    Every single time there is information available, the server push it to all the clients connected to it.

    The deadlock occur if the client send something to the server,
    the socket(in the server side) is in the slotReadyRead reading the buffer.
    and there some new information that needs to be send to the through the same sockets.
    At this point the deadlock is present.

    Is there some alternative?
    is it really needed to have guards in socket class, thread-safe?
    is it enough to guarantee that is re-entrant?
    I assure that function in the socket is always called from the thread that creates it (thread1) using signal/slot.

    Any help is appreciated.

    CAFU

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by cafu1007 View Post
    The Server lives in working thread1
    What for?

    Is there some alternative?
    Yes, don't use threads if they don't give you any benefits.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    Even if i dont use a thread for the server i still need a thread for the background, and when everything is guard with mutex the deadlock will be present again in similar situation.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by cafu1007 View Post
    Even if i dont use a thread for the server i still need a thread for the background
    You probably don't need a thread for that too.

    If you have a deadlock then it means you're not using mutexes properly. If you share some code, maybe we can come up with an alternative design.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    OK here is some Code

    code for CSocket and CSocketPrivate:
    Qt Code:
    1. void CSocket::connectToHost(const QString &hostName, quint16 port)
    2. {
    3. L_D(CSocket);
    4. QMutexLocker locker(&d->m_mMutex);
    5. d->connectToHost(hostName, port);
    6. }
    7. void CSocketPrivate::connectToHost(const QString &hostName, quint16 port)
    8. {
    9. QTcpSocket::connectToHost(hostName, port);
    10. }
    11. void CSocketPrivate::slotConnect(QString hostName, quint16 port)
    12. {
    13. QMutexLocker locker(&m_mMutex);
    14. QTcpSocket::connectToHost(hostName, port);
    15. m_wcConnected.wakeAll();
    16. }
    17. qint64 CSocket::send(const CTCPFrame &frame)
    18. {
    19. L_D(CSocket);
    20. QMutexLocker locker(&d->m_mMutex);
    21. return d->send(frame);
    22. }
    23. qint64 CSocketPrivate::send(const CFrame &frame)
    24. {
    25. QByteArray data;
    26. data = frame.serialize();
    27. return send(data);;
    28. }
    29. qint64 CSocketPrivate::send(const QByteArray &message)
    30. {
    31. qint64 Error = QTcpSocket::write(message);
    32. flush();
    33. return Error;
    34. }
    35. void CLLSocketPrivate::slotReadyRead()
    36. {
    37. QMutexLocker locker(&m_mMutex);
    38. readTime->stop();
    39. readBuffer();
    40. readTime->start();
    41. }
    To copy to clipboard, switch view to plain text mode 

    Code for Server and ServerPrivate:
    Qt Code:
    1. CSvrNetControlPrivate::CSvrNetControlPrivate(QPointer<QObject> parent, qint32 port, bool bIpv6) :
    2. QTcpServer(parent)
    3. {
    4. m_mMutex.lock();
    5. m_Thread.start();
    6. moveToThread(&m_Thread);
    7. m_mMutex.unlock();
    8. }
    9. void CSvrNetControlPrivate::incomingConnection(int socketDescriptor)
    10. {
    11. QMutexLocker locker(&m_mMutex);
    12. newClient(socketDescriptor);
    13. }
    14. void CSvrNetControlPrivate::newClient(int socketDescriptor)
    15. {
    16. if (QThread::currentThread() != &m_Thread)
    17. {
    18. emit
    19. signalNewClient(socketDescriptor);
    20. if (!m_wcNewClientDone.wait(&m_mMutex, 10000))
    21. {
    22. qWarning() << "CSvrNetControl::newClient m_wcNewClientDone no triggered";
    23. return;
    24. }
    25. }
    26. else
    27. {
    28. makeNewClient(socketDescriptor);
    29. }
    30. }
    31. void CSvrNetControlPrivate::slotNewClient(int socketDescriptor)
    32. {
    33. QMutexLocker locker(&m_mMutex);
    34. makeNewClient(socketDescriptor);
    35. m_wcNewClientDone.wakeAll();
    36. }
    37. void CSvrNetControlPrivate::makeNewClient(int socketDescriptor)
    38. {
    39. QPointer<CSocket> socket = new CSocket(this);
    40. if (!socket->setSocketDescriptor(socketDescriptor))
    41. {
    42. delete socket;
    43. socket = 0;
    44. return;
    45. }
    46. m_lSocket.append(socket);
    47. connect(m_lSocket.last(), SIGNAL(disconnected()), this, SLOT(slotConnectionClosed()));
    48. connect(m_lSocket.last(), SIGNAL(signalMessageReceived(CFrame)), this, SLOT(slotMessageReceived(CFrame)));
    49. L_Q(CSvrNetControl);
    50. emit q->signalNewClientConnected(m_lSocket.last()->peerAddress().toString());
    51. }
    52. void CSvrNetControl::broadcastMessage(const CFrame &frame)
    53. {
    54. L_D(CSvrNetControl);
    55. QMutexLocker locker(&d->m_mMutex);
    56. return d->broadcastMessage(frame);
    57. }
    58. void CSvrNetControlPrivate::broadcastMessage(const CFrame &frame)
    59. {
    60. for (qint32 i = 0; i < m_lSocket.size(); i++)
    61. {
    62. sendMessagePrivate(m_lSocket.at(i), frame);
    63. }
    64. }
    65. void CSvrNetControlPrivate::sendMessagePrivate(QPointer<CSocket> client, const CFrame &frame)
    66. {
    67. if ((QThread::currentThread() != &m_Thread))
    68. {
    69. emit signalSend(client, frame);
    70. if (!m_wcSended.wait(&m_mMutex, 10000))
    71. {
    72. qWarning() << "CSvrNetControl::sendMessagePrivate m_wcSended no triggered" << QThread::currentThreadId();
    73. m_eError = CErrorDescription(-1, "Not Performed");
    74. }
    75. }
    76. else
    77. {
    78. sendMessage(client, frame);
    79. }
    80. }
    81. void CSvrNetControlPrivate::slotSend(QPointer<CSocket> client, const CFrame &frame)
    82. {
    83. QMutexLocker locker(&m_mMutex);
    84. sendMessage(client, frame);
    85. m_wcSended.wakeAll();
    86. }
    87. void CSvrNetControlPrivate::sendMessage(QPointer<CSocket> client, const CFrame &frame)
    88. {
    89. if (client)
    90. {
    91. client->send(frame);
    92. }
    93. }
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    You cannot access sockets from multiple threads. If you insist on using threads, each QObject doing something in the background (like QTcpSocket or QTcpServer) can only be accessed from a single thread. Mutexes will not help here, it's a matter of Qt's internal design. You have to post a request to an object living in the thread handling the socket and then handle that request in the proper thread.

    However you really don't need any extra threads here. You can take the code above, strip it of all mutexes, run it in the gui thread and it will work just fine and faster than if you used threads.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by wysota View Post
    You have to post a request to an object living in the thread handling the socket and then handle that request in the proper thread.
    I assure this by signaling to the proper thread. this is working right...

    Quote Originally Posted by wysota View Post
    However you really don't need any extra threads here. You can take the code above, strip it of all mutexes, run it in the gui thread and it will work just fine and faster than if you used threads.
    So i am not getting any benefits from using threads here, but the amount of information being handle is very big. there is new values coming from serial ports (5) around 10 values/sec from each port that have to "deserialize", analyze and do specific actions.
    The gui displays this information assign it to specific widget and has to send it to the clients, when there is many clients connected, will the gui have a latency?

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by cafu1007 View Post
    I assure this by signaling to the proper thread. this is working right...
    No, you don't assure anything. If you did, you wouldn't need mutexes. If you protect socket access by a mutex then it means that you expect more than one thread to access it.
    The fact that you call a method from an object that is somehow associated with a thread, doesn't mean you call the method in the context of that thread.

    So i am not getting any benefits from using threads here, but the amount of information being handle is very big. there is new values coming from serial ports (5) around 10 values/sec from each port that have to "deserialize", analyze and do specific actions.
    Unless you have a really old machine, one thread is sufficient. If you have a really old machine, using more than one thread won't help if you have just a single CPU machine.

    The gui displays this information assign it to specific widget and has to send it to the clients, when there is many clients connected, will the gui have a latency?
    No, unless you have hundreds or thousands of high-traffic simultaneous connections (provided your network interface can cope with it). Currently you waste lot of time on locking and context switching without any benefits whatsoever.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by wysota View Post
    No, you don't assure anything. If you did, you wouldn't need mutexes.
    I use mutex if another thread try to access the CSocketPrivate class will emit a signal what will assure that the QTCPSocket functions are called in the thread that they have affinity...
    maybe i dont need the usage of mutex for that, only with triggering the signal would be enough, or?

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by cafu1007 View Post
    I use mutex if another thread try to access the CSocketPrivate class
    You contradict yourself. Either only one thread accesses the data or not.

    maybe i dont need the usage of mutex for that, only with triggering the signal would be enough, or?
    You don't need threads. You're putting a lot of effort in trying to synchronize something that doesn't need synchronization. Just use signals and slots in one thread and it will work properly.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. The following user says thank you to wysota for this useful post:

    cafu1007 (26th September 2012)

  12. #11
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    there is a public class(CSocket) and a private class(CSocketPrivate) if one want to send something have to go through the public class and if a this point the calling thread is not the one with the affinity a signal will be emitted,
    i am not contradicting myself (I think ).

    Well i have followed your the advice remove the threads, and mutex, is wroking good, Thanks.
    Last edited by cafu1007; 26th September 2012 at 15:59.

  13. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by cafu1007 View Post
    there is a public class(CSocket) and a private class(CSocketPrivate) if one want to send something have to go through the public class and if a this point the calling thread is not the one with the affinity a signal will be emitted,
    i am not contradicting myself (I think ).
    Affinity of the signal doesn't matter. What matters is the context in which the socket is accessed.


    I have one problem the client application is receiving very delayed what the server sends. Why? is it normal? how can i make the client to empty the buffer faster? the reading of the buffer is done using a timer with 50ms interval.
    Hard for me to say without seeing the actual code. It might be that you're blocking execution of the thread with something (like a mutex or a blocking call to a device).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  14. #13
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    The problem of this solution without thread is if the main thread gets block because of re-sizing, moving the GUI or anything else that blocks the main thread, everything else will stop. And i need to know if a value from the one being reading from the serial port changes and its in a critical range to do an action according to this...


    Added after 6 minutes:


    Quote Originally Posted by wysota View Post
    Hard for me to say without seeing the actual code. It might be that you're blocking execution of the thread with something (like a mutex or a blocking call to a device).
    There was stuff in the buffer but I was not making it empty properly.
    Last edited by cafu1007; 26th September 2012 at 16:32.

  15. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by cafu1007 View Post
    The problem of this solution without thread is if the main thread gets block because of re-sizing, moving the GUI or anything else that blocks the main thread, everything else will stop.
    The actions you mention do not block the thread.

    And i need to know if a value from the one being reading from the serial port changes and its in a critical range to do an action according to this...
    In that case using sockets is a bad idea at all. So is using a non-RT operating system. It can always happen that your application gets frozen by the operating system for a number of miliseconds. Threads will not help in any way here. Time critical conditions need real time operating systems. So it's either getting a real-time operating system or accepting that at times things can temporarily go out of control.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  16. #15
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    HI There, as i was recommended i am not using thread any where. Everything is running in a single thread (The main). but during debugging i see that at least 6 thread are created.

    is the any Qt class that creates new thread silently?

  17. #16
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    Quote Originally Posted by cafu1007 View Post
    is the any Qt class that creates new thread silently?
    Yes, QFileSystemModel.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  18. #17
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QTCP Socket Server and threads

    Also QNetworkAccessManager for HTTP requests: http://blog.qt.digia.com/2011/04/29/...accessmanager/

  19. #18
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    HI There,

    I was told that press down click event on the gui wil not stop the event loop.
    I monitor what is send and received in the serial port. When i hold down the mouse over the title bar for moving the Windows, there is not receiving information (i would say not read) from the serial port, i used Qextserialport class for serial communication. is this a Qt problem, Qextserialport or simply a block on the event loop?

    Thanks

  20. #19
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTCP Socket Server and threads

    This is somehow related to Windows display system. Qt has no influence on it since the title bar is not part of your application.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  21. #20
    Join Date
    May 2009
    Posts
    56
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTCP Socket Server and threads

    So how could i get around this. if i am not using threads. this is unwanted situation since everything should remain responding and communication should remain.

Similar Threads

  1. How to disconnenct socket in server side?
    By Ali Reza in forum Newbie
    Replies: 1
    Last Post: 6th June 2012, 10:26
  2. Wait in thread till QTcp socket have some thing to read
    By hasnain in forum Qt Programming
    Replies: 2
    Last Post: 14th September 2010, 12:46
  3. threads and socket
    By babu198649 in forum Newbie
    Replies: 3
    Last Post: 10th April 2008, 15:34
  4. non GUI socket server
    By pdoria in forum Qt Programming
    Replies: 1
    Last Post: 3rd January 2008, 11:15
  5. question about socket and threads?
    By oob2 in forum Qt Programming
    Replies: 2
    Last Post: 27th February 2007, 11:42

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.