以下线程代码运行2058次,之后崩溃。有人可以帮我找出原因吗?该程序的想法是在主线程中创建一些类,将其传递给工作线程,线程填充所需的数据并将数据传递回主线程。此示例在2058次运行后崩溃,但它应该无限期地进行。我已经运行了20次,总是相同的数字。在简化的qWarning()调用版本中(每100次运行打印简单行),线程执行3000次。所以我猜它不依赖于qWarning()调用的数量。为什么SharedData * d的指针地址总是一样的?
的main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TestThread* thread = new TestThread();
MainWindow w(thread);
w.show();
delete thread;
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
#include <QThread>
#include <QHash>
class SharedData
{
public:
SharedData();
QString var;
QHash<QString, QString> hash;
};
class TestThread : public QThread
{
Q_OBJECT
public:
TestThread(QObject *parent = 0);
void doWork(SharedData* _data);
void doCrash(QHash<QString, QString>* hash);
signals:
void completed(SharedData* d);
private:
SharedData* data;
protected:
void run();
};
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(TestThread* t, QWidget *parent = 0);
~MainWindow();
void runThread();
public slots:
void jobDone(SharedData* req);
private:
Ui::MainWindow *ui;
TestThread* t;
int runcount;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug.h>
TestThread::TestThread(QObject *parent) : QThread(parent)
{
}
void TestThread::run()
{
qWarning() << "Thread running";
data->var = "hello";
doCrash(&data->hash);
emit completed(data);
}
void TestThread::doWork(SharedData* _data)
{
data = _data;
qWarning() << "Attempting to start";
if(!isRunning())
{
run();
}
else
{
qWarning() << "Oops. Already running";
}
}
void TestThread::doCrash(QHash<QString, QString>* hash)
{
hash->insert("test", "123");
/*
QHashIterator<QString, QString> i(*hash);
while (i.hasNext()) {
i.next();
qWarning() << i.key() + ":" + i.value();
}
*/
}
SharedData::SharedData()
{
}
void MainWindow::jobDone(SharedData* req)
{
qWarning() << "RETURNED";
qWarning() << "var: " << req->var << " addr: " << &req->var;
qWarning() << "cnt: " << req->hash.count() << " addr: " << &req->hash;
QHashIterator<QString, QString> i(req->hash);
while (i.hasNext()) {
i.next();
qWarning() << i.key() + ":" + i.value();
}
delete req;
runThread();
}
MainWindow::MainWindow(TestThread* _t, QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
t = _t;
connect(t, SIGNAL(completed(SharedData*)), this, SLOT(jobDone(SharedData*)));
runcount = 0;
runThread();
}
void MainWindow::runThread()
{
SharedData* d = new SharedData();
d->var = "test";
runcount++;
qWarning() << "Run count: " << runcount;
qWarning() << "CREATING THREAD";
qWarning() << "var: " << d->var << " addr: " << &d->var;
qWarning() << "cnt: " << d->hash.count() << " addr: " << &d->hash;
t->doWork(d);
}
MainWindow::~MainWindow()
{
delete ui;
}
答案 0 :(得分:2)
你不应该在main.cpp中删除你的TestThread实例(注释掉“删除线程;”字符串)!
答案 1 :(得分:2)
正如vnm所指出的,崩溃的原因很可能是main.cpp中的delete thread;
指令:当你调用w.show()它会立即返回时,它是exec()调用将启动事件循环和阻止,但到那时已经太晚了,因为线程已被删除。
我会将该线程声明为主窗口的非指针成员,而不是将其作为参数传递,这样编译器就会为您进行清理和初始化。 更简单的解决方案是使用QtConcurrent::run。通过这样做,您将消除所有显式的踩踏代码,但仍然可以获得多线程的好处。