Results 1 to 4 of 4

Thread: emit() call in QThread occasionally blocks and freezes GUI

  1. #1
    Join Date
    Nov 2013
    Posts
    2
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default emit() call in QThread occasionally blocks and freezes GUI

    Hello everyone!

    I am currently programming a GUI to display some results from a different C++ program using qwt plots. The results are transferred via 4 TCP links and are received in 4 QThreads. Each QThread sends the received data via a signal to a slot of the GUI to display the data in the plots. Each thread sends on average something like 5-10 signals per second. For a while everything is working fine (I am running the GUI under cygwin), but occasionally my GUI freezes. Sometimes this happens 5 minutes after starting the GUI and TCP data transfer, sometimes it happens after 2 hours. After some debugging it seems that the emit() calls block the QThreads. Interestingly, a very similar GUI programmed using exactly the same approach (but using only a single QThread) works absolutely fine. My (simplified) code looks as follows:

    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QApplication a(argc, argv);
    4.  
    5. qRegisterMetaType<QSharedPointer<CPacket> >();
    6.  
    7. RodGui w;
    8. w.show();
    9. return a.exec();
    10. }
    11. Q_DECLARE_METATYPE(QSharedPointer<CPacket>)
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. class RodGui : public QMainWindow
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. RodGui(QWidget *parent = 0);
    7. ~RodGui();
    8.  
    9. private:
    10. void setupAndStartNetwork();
    11.  
    12. Network* networkThreadMi;
    13. Network* networkThreadBer;
    14. Network* networkThreadBuffer;
    15. Network* networkThreadQam;
    16.  
    17. //[qwt plot stuff and widgets]
    18.  
    19. private slots:
    20. void updatePlot(QSharedPointer<CPacket> packet);
    21. };
    22.  
    23.  
    24. RodGui::RodGui(QWidget *parent) : QMainWindow(parent)
    25. {
    26. // [create widgets and qwt plots]
    27. setupAndStartNetwork();
    28. }
    29.  
    30.  
    31. void RodGui::updatePlot(QSharedPointer<CPacket> packet) {
    32. // [do some calculations with packet and update qwt plots]
    33. }
    34.  
    35. void RodGui::setupAndStartNetwork() {
    36.  
    37. networkThreadMi = new Network(this, QString::number(20004));
    38. networkThreadBer = new Network(this, QString::number(20005));
    39. networkThreadBuffer = new Network(this, QString::number(20006));
    40. networkThreadQam = new Network(this, QString::number(20007));
    41.  
    42. QObject::connect(networkThreadMi, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
    43. this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
    44. QObject::connect(networkThreadBer, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
    45. this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
    46. QObject::connect(networkThreadBuffer, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
    47. this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
    48. QObject::connect(networkThreadQam, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
    49. this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
    50.  
    51. networkThreadMi->start();
    52. networkThreadBer->start();
    53. networkThreadBuffer->start();
    54. networkThreadQam->start();
    55. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. class Network : public QThread {
    2. Q_OBJECT
    3.  
    4. public:
    5. Network(QWidget *parent = 0, QString port = 0);
    6.  
    7. signals:
    8. void processedDatagramsReady(QSharedPointer<CPacket>);
    9.  
    10. private:
    11. QString port;
    12. //[TCP stuff (boost asio)]
    13.  
    14. protected:
    15. void run();
    16. };
    17.  
    18. void Network::run() {
    19.  
    20. while (true) {
    21. //[read some TCP packets via boost asio and deserialize to a class (derived from CPacket)]
    22. qDebug() << "emit: " << port;
    23. emit processedDatagramsReady(packet);
    24. qDebug() << "emit complete: " << port;
    25. }
    26. }
    To copy to clipboard, switch view to plain text mode 

    When my GUI freezes the last debug output on my console looks like this:
    [...]
    emit: xx
    emit complete: xx
    emit: 20004
    emit: 20005
    emit: 20006
    emit: 20007

    So it seems that the event loop is freezing after some time, blocking the emit calls from all QThreads. Is there a problem with the approach itself? Or am I simply firing too many signals per second? Any idea what might cause this problem?

    Thanks in advance!
    Jan

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: emit() call in QThread occasionally blocks and freezes GUI

    maybe the reading is blocking? (the code which is NOT present - what ever is happening in the comment)
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: emit() call in QThread occasionally blocks and freezes GUI

    Have you checked if your updatePlots slot blocks?

    Cheers,
    _

  4. The following user says thank you to anda_skoa for this useful post:

    CreeperBS (11th November 2013)

  5. #4
    Join Date
    Nov 2013
    Posts
    2
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: emit() call in QThread occasionally blocks and freezes GUI

    The network connection is definitely not blocking. I guess even if it would block it wouldn't cause the GUI to freeze, since the sockets run in different QThreads.

    But it indeed seems to be the case that the updatePlots() slot is blocking! I never considered that since the slot only contains some simple lines adding data to six qwt plots. But it seems that something is wrong here. No I only need to find out which qwt call blocks the slot.

    Thanks for your help!

Similar Threads

  1. Replies: 4
    Last Post: 16th June 2013, 08:49
  2. Emit signal outside run() in QThread
    By naturalpsychic in forum Qt Programming
    Replies: 4
    Last Post: 26th March 2012, 16:31
  3. QThread blocks gui
    By skoegl in forum Newbie
    Replies: 6
    Last Post: 29th October 2007, 12:09
  4. QThread, QFile and QTcpSocket freezes GUI
    By naresh in forum Qt Programming
    Replies: 1
    Last Post: 23rd June 2006, 23:25
  5. Workload in a QThread blocks main application's event loop ?
    By 0xBulbizarre in forum Qt Programming
    Replies: 14
    Last Post: 9th April 2006, 21:55

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.