我正在学习如何在不同的线程上运行对象。我从这个简单的练习开始,在不同的线程上运行对象并在它们之间进行通信。现在,我无法终止程序。主要退出时如何安全地销毁在不同线程中运行的对象?如果我在main之前对线程进行等待以完成线程,程序将挂起在wait()。如果我没有等待,则永远不会执行线程,并且主要退出时会立即删除线程。
--------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();
}
答案 0 :(得分:3)
你正在做一些时髦的事情。
1)每个QThread
被start()
调用两次 - 首先在testThread
构造函数中,然后再在main()
中。第二个调用不会执行任何操作,因为已经在运行。
2)当您在QThread
构造函数中启动testThread
时,您的循环将在连接之前执行并发出信号 - 这让我觉得您实际上并不想启动该线程在构造函数中,而不是在main()
中稍后将其保持为未启动。
3)QThread::quit()
将导致线程的事件循环返回 - 这就是你所缺少的。 connect
从testThread
到quit
插槽的“完成”类型信号,然后QThread::wait()
将按预期运行,并且一旦完成循环,调用就会返回。 / p>
4)我知道这只是一个小测试程序,但是由于你没有在delete
对象上调用new
,所以你会泄漏内存。实际上你根本不需要使用new
,一切都可以在堆栈上分配 - 通常是一个更好的主意。
答案 1 :(得分:0)
不要在threa \ ds上等待以防止主线程退出。可能等待STDIN或其他一些输入?
等待/加入线程只应在绝对需要时才能完成(例如,必须刷新/关闭文件,必须提交事务,必须关闭数据库连接)。如果你经常加入/等待所有线程只是因为它似乎是一个好主意,你最终会编写一大堆复杂的代码来让线程退出 - 这通常是不必要的。