[solved] Qthread start() causing SIGSEGV Segmentation fault
-
Hi Cerebrates!
Could anybody take a look why I'm having SIGSEGV crash while starting new thread?
@
// STUDENTS CLASS
class students : public QObject
{
Q_OBJECTpublic:
explicit students(QObject *parent = 0);
void DoSetup(QThread &sThread);public slots:
void doWork();
// (...)
};// MAINWINDOW CLASS
class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);private:
students student;
// (...)
};// IMPLEMENTATIONS
void students::DoSetup(QThread &sThread)
{
connect(&sThread, SIGNAL(started()), this, SLOT(doWork())); // SIGSEGV: Segmentation fault
}void students::doWork()
{
// (...)
}void MainWindow::on_pushButton_clicked()
{
QThread sThread;
student.DoSetup(sThread);
student.moveToThread(&sThread);
sThread.start();
}
@No compiling errors and syntax looks fine for me. So what's wrong?
-
[quote author="shimano" date="1364920935"]
@
void MainWindow::on_pushButton_clicked()
{
QThread sThread;
student.DoSetup(sThread);
student.moveToThread(&sThread);
sThread.start();
}
@
[/quote]That section is not healthy. Presumably called when you press a push button. QThread is created at the begin of method, but deleted directly at the end. That is causing the problem.
-
It sounds logically but what implementation should be applied to push it work and keep healthy?
My code is based on "this Brian's tutorial":http://www.youtube.com/watch?v=yazMHbIew0Q
-
[quote author="shimano" date="1364920935"]
@
// MAINWINDOW CLASS
class MainWindow : public QMainWindow
{
Q_OBJECTQThread *MyThread;
public:
explicit MainWindow(QWidget *parent = 0);private:
students student;
// (...)
};void MainWindow::on_pushButton_clicked()
{
MyThread = new QThread;
student.DoSetup(MyThread);
student.moveToThread(MyThread);
MyThread->start();
}
@
[/quote]This looks better for the logic. However, it has not been tested. Brain dump to keyboard ;-)
-
Moving definition of QThread object to header helped in 50%. Thread run and worked fine but probably it never finished because i couldn't run thread again.
I've modified code as "documentation suggested":http://qt-project.org/doc/qt-4.8/qthread.html#details and it works! Even in my opinion it looks - as you said - healthy. I'm not sure it'll be stable for advanced use but definitly it's enough for begining stage.
I will work with this solution in few more examples and I will try go to next step - managing and communicating threads. I hope I'll get it without trolling forum with lame questions but you can expect another thread from me :)
P.S.
I'm not sure how to write threading-method correctly. My current code is:
@
void MainWindow::on_pushButton_clicked()
{
student.threadWork(student);
}void students::threadWork(students &studentObj)
{
QThread *myThread = new QThread(this);
connect(myThread, SIGNAL(started()), this, SLOT(doWork()));
connect(myThread, SIGNAL(finished()), this, SLOT(deleteLater()));
studentObj.moveToThread(myThread);
myThread->start();
}void students::doWork()
{
// (...)
}
@But is threadWork(students &studentObj) a correct way?
I don't like to create new object only for thread. I would like to use existing object (student) and only run his method in new thread, so my invention is to use a reference, but i'm not 100% sure of that.
-
Good to see, that you moved forward. The implementation of threadWork seems right to me. As I see, you have consulted a bit the documentation and did it the Qt way. I tend to do it more traditional and certainly some handling was missing in my suggestion.
C++ invented the references for calling lists. Those are "easier" to use than pointers. However, sometimes pointers are the better solution for sure, see your thread issues above.
@
void foo ( int & var )
{
++var;
}
void foo1 ()
{
int var1 = 0;
foo ( var1 );
}
@See this simple example. Function foo has a reference. Function foo1 creates var1 and hands it over to foo for the "calculation". Since foo is called directly, that should not be a problem. var1 is existing as long as required in foo. However, for the sake of explanation just assume what is happening when foo would continue to run when foo1 is already finished?
You would run into the same issue as above. For sure this is a stupid, not working example, but close to your threading, it highlights what you need to consider. So, using a pointer and keeping it somewhere save, is a good idea.