I am learning how to run objects on different threads. I started with this simple exercise to run objects on different threads and communicate between them. Now, I have trouble terminating the program. How to safely destroy the objects running in different threads when main exits? If I put a wait on threads before main for the completion of threads, the program hangs at wait(). If I don’t put a wait, threads are never executed and threads are deleted immediately as main exits.
--------testthread.h------------------
#ifndef TESTTHREAD_H
#define TESTTHREAD_H
#include <QThread>
#include <QApplication>
#include <string>
#include <iostream>
using namespace std;
class testThread : public QObject
{
Q_OBJECT
public:
testThread(const string&, QThread*);
~testThread();
private:
QThread* thread;
string _threadName;
signals:
void requestCalculateSquare(int);
public slots:
void calculateSquare(int);
void start();
};
#endif // TESTTHREAD_H}
-----testthread.cpp---------------------
#include "testthread.h"
#include <iostream>
//#include "moc_testthread.cpp"
testThread::~testThread()
{}
testThread::testThread(const string& threadName, QThread* thread):QObject()
{
_threadName = threadName;
moveToThread(thread);
connect(thread, SIGNAL(started()),this,SLOT(start()));
}
void testThread::calculateSquare(int i)
{
cout<<_threadName<<" "<<i*i;
}
void testThread::start()
{
for(int i=0;i<10;++i)
{
emit requestCalculateSquare(i);
}
emit finished();
}
--------main.cpp--------------------------
#include <iostream>
#include <QtCore/QCoreApplication>
#include <string>
#include "testthread.h"
using namespace std;
int main(int argc, char** argv)
{
QApplication app(argc,argv);
string name1("Thread1");
string name2("Thread2");
QThread* thread1 = new QThread;
QThread* thread2 = new QThread;
testThread* test1 = new testThread(name1, thread1);
testThread* test2 = new testThread(name2, thread2);
QObject::connect(test1,SIGNAL(requestCalculateSquare(int)),test2,SLOT(calculateSquare(int)));
QObject::connect(test2,SIGNAL(requestCalculateSquare(int)),test1,SLOT(calculateSquare(int)));
QObject::connect(test1,SIGNAL(finished()),test2, SLOT(deleteLater()));
QObject::connect(test1,SIGNAL(finished()),thread2, SLOT(quit()));
QObject::connect(test2,SIGNAL(finished()),test1, SLOT(deleteLater()));
QObject::connect(test2,SIGNAL(finished()),thread1, SLOT(quit()));
thread1->start();
thread2->start();
thread1->wait();
thread2->wait();
cout << "Hello World!" << endl;
return 0;
//return app.exec();
}
You’re doing some funky things.
1) Each
QThreadis havingstart()called twice – first in thetestThreadconstructor, then again inmain(). The second call won’t do anything, since is is already running.2) When you start the
QThreadin thetestThreadconstructor, your loop will execute and emit the signals before they are connected – it makes me think you don’t actually want to start the thread in the constructor, and instead leave it unstarted until later inmain().3)
QThread::quit()will cause the thread’s event loop to return – this is what you’re missing.connecta “done” type signal fromtestThreadto thequitslot, and thenQThread::wait()will behave as you expect, with the calls returning once the loops are completed.4) I know it’s just a little test program, but you’re leaking memory since you aren’t calling
deleteon yournewobjects. You actually don’t need to usenewat all here, everything can be allocated on the stack – generally a better idea.