PDA

View Full Version : without Qt::QueuedConnection will crash



hashb
1st December 2010, 06:21
Hi, All

I do a testing which use a work thread to access a variable (here is str) which belong to main thread. I found if I add QueuedConnection in connect function ,it will not crash,but without it will crash .

Does anybody know why?

Thanks advance for your help.



#ifndef AAA_
#define AAA_
#include <QThread>
#include <QString>
#include <QDebug>
class myClass : public QThread
{
Q_OBJECT
public:
myClass ()
{
connect(this,
SIGNAL(startSignal()),
this, SLOT(onDoComm())); //will crash
//,Qt::QueuedConnection); //add this parameter will not
}
void run() { exec(); }
void startComm() {emit startSignal();}
signals:
void startSignal();
public slots:
void onDoComm()
{
static long i=1;
qDebug()<<str;
str=QString("%1%2").arg(i++);
emit startSignal();
};
private:
QString str;
};


#endif



#include <iostream>
#include <QApplication>
#include "aaa.h"

using namespace std;
int main(int argc ,char *argv[])
{
QApplication app(argc, argv);

myClass a;
a.start();
a.startComm();
app.exec();
}

tbscope
1st December 2010, 06:27
Read this:
http://doc.qt.nokia.com/4.7/threads.html
and this:
http://doc.qt.nokia.com/4.7/signalsandslots.html
and this:
http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/

Lesiok
1st December 2010, 06:31
Because without Qt::QueuedConnection emmiting signal is like a calling slot function. So You call onDoComm() BEFORE ending this method that is to say "classic stack overflow".
With Qt::QueuedConnection slot function is calling by signal dispatcher in idle time.

Question is : why You emit StartSignal() in onDoComm() ?

tbscope
1st December 2010, 06:33
Here the big problem is that you're dealing with two distinct event loops.
Even with a queued connection, the logic is still wrong as the slot of the thread is not executed in the thread itself but in the main thread resulting in possible crashes.

Edit: never mind, the connection is made in the main thread. Just ignore this post.

hashb
1st December 2010, 07:07
Hi tbscope,you mean the slot of the thread executed in the main thread ?



Here the big problem is that you're dealing with two distinct event loops.
Even with a queued connection, the logic is still wrong as the slot of the thread is not executed in the thread itself but in the main thread resulting in possible crashes.

Edit: never mind, the connection is made in the main thread. Just ignore this post.

Thanks a lot for you explanation,
it was just a test in order to produce a loop


Because without Qt::QueuedConnection emmiting signal is like a calling slot function. So You call onDoComm() BEFORE ending this method that is to say "classic stack overflow".
With Qt::QueuedConnection slot function is calling by signal dispatcher in idle time.

Question is : why You emit StartSignal() in onDoComm() ?

Lesiok
2nd December 2010, 07:28
Hi tbscope,you mean the slot of the thread executed in the main thread ?




Thanks a lot for you explanation,
it was just a test in order to produce a loop
Do this with QTimer. Something like this :
#ifndef AAA_
#define AAA_
#include <QThread>
#include <QString>
#include <QDebug>
#include <QTimer>

class myClass : public QThread
{
Q_OBJECT
public:
myClass ()
{
connect(&timer,
SIGNAL(timeout()),
this, SLOT(onDoComm()));
}
void run() { exec(); }
void startComm() {timer.start(10);}
signals:
void startSignal();
public slots:
void onDoComm()
{
static long i=1;
qDebug()<<str;
str=QString("%1%2").arg(i++);
};
private:
QString str;
QTimer timer;
};
#endif
In this example onDoComm will be executed one time per 10 ms