CreeperBS
11th November 2013, 10:47
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:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qRegisterMetaType<QSharedPointer<CPacket> >();
RodGui w;
w.show();
return a.exec();
}
Q_DECLARE_METATYPE(QSharedPointer<CPacket>)
class RodGui : public QMainWindow
{
Q_OBJECT
public:
RodGui(QWidget *parent = 0);
~RodGui();
private:
void setupAndStartNetwork();
Network* networkThreadMi;
Network* networkThreadBer;
Network* networkThreadBuffer;
Network* networkThreadQam;
//[qwt plot stuff and widgets]
private slots:
void updatePlot(QSharedPointer<CPacket> packet);
};
RodGui::RodGui(QWidget *parent) : QMainWindow(parent)
{
// [create widgets and qwt plots]
setupAndStartNetwork();
}
void RodGui::updatePlot(QSharedPointer<CPacket> packet) {
// [do some calculations with packet and update qwt plots]
}
void RodGui::setupAndStartNetwork() {
networkThreadMi = new Network(this, QString::number(20004));
networkThreadBer = new Network(this, QString::number(20005));
networkThreadBuffer = new Network(this, QString::number(20006));
networkThreadQam = new Network(this, QString::number(20007));
QObject::connect(networkThreadMi, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
QObject::connect(networkThreadBer, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
QObject::connect(networkThreadBuffer, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
QObject::connect(networkThreadQam, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
networkThreadMi->start();
networkThreadBer->start();
networkThreadBuffer->start();
networkThreadQam->start();
}
class Network : public QThread {
Q_OBJECT
public:
Network(QWidget *parent = 0, QString port = 0);
signals:
void processedDatagramsReady(QSharedPointer<CPacket>);
private:
QString port;
//[TCP stuff (boost asio)]
protected:
void run();
};
void Network::run() {
while (true) {
//[read some TCP packets via boost asio and deserialize to a class (derived from CPacket)]
qDebug() << "emit: " << port;
emit processedDatagramsReady(packet);
qDebug() << "emit complete: " << port;
}
}
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
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:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qRegisterMetaType<QSharedPointer<CPacket> >();
RodGui w;
w.show();
return a.exec();
}
Q_DECLARE_METATYPE(QSharedPointer<CPacket>)
class RodGui : public QMainWindow
{
Q_OBJECT
public:
RodGui(QWidget *parent = 0);
~RodGui();
private:
void setupAndStartNetwork();
Network* networkThreadMi;
Network* networkThreadBer;
Network* networkThreadBuffer;
Network* networkThreadQam;
//[qwt plot stuff and widgets]
private slots:
void updatePlot(QSharedPointer<CPacket> packet);
};
RodGui::RodGui(QWidget *parent) : QMainWindow(parent)
{
// [create widgets and qwt plots]
setupAndStartNetwork();
}
void RodGui::updatePlot(QSharedPointer<CPacket> packet) {
// [do some calculations with packet and update qwt plots]
}
void RodGui::setupAndStartNetwork() {
networkThreadMi = new Network(this, QString::number(20004));
networkThreadBer = new Network(this, QString::number(20005));
networkThreadBuffer = new Network(this, QString::number(20006));
networkThreadQam = new Network(this, QString::number(20007));
QObject::connect(networkThreadMi, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
QObject::connect(networkThreadBer, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
QObject::connect(networkThreadBuffer, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
QObject::connect(networkThreadQam, SIGNAL(processedDatagramsReady(QSharedPointer<CPacket>)),
this, SLOT(updatePlot(QSharedPointer<CPacket>)), Qt::QueuedConnection);
networkThreadMi->start();
networkThreadBer->start();
networkThreadBuffer->start();
networkThreadQam->start();
}
class Network : public QThread {
Q_OBJECT
public:
Network(QWidget *parent = 0, QString port = 0);
signals:
void processedDatagramsReady(QSharedPointer<CPacket>);
private:
QString port;
//[TCP stuff (boost asio)]
protected:
void run();
};
void Network::run() {
while (true) {
//[read some TCP packets via boost asio and deserialize to a class (derived from CPacket)]
qDebug() << "emit: " << port;
emit processedDatagramsReady(packet);
qDebug() << "emit complete: " << port;
}
}
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