为什么我用std :: thread创建新线程后GUI崩溃?我收到的唯一输出是:
传递给C运行时函数的参数无效。
无效的参数传递给C运行时函数。
仅这两行和来自Windows的消息,即应用程序已请求运行时以一种异常方式终止它。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QBoxLayout>
#include <QPushButton>
#include <thread>
#include <iostream>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPushButton* button = new QPushButton;
button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QGridLayout *layout = new QGridLayout;
connect(button, SIGNAL(released()), this, SLOT(buttonSignal()));
layout->addWidget(button);
centralWidget()->setLayout(layout);
}
void foo(){
//want to do stuff in here
}
void MainWindow::buttonSignal(){
std::thread thread (foo);
}
MainWindow::~MainWindow()
{
delete ui;
}
答案 0 :(得分:3)
问题是您的thread
对象在MainWindow::buttonSignal
中是本地对象,并且在销毁之前没有加入,这是导致std::terminate
being called的运行时错误。
您可以使线程对象成为MainWindow
类的成员,然后在MainWindow::buttonSignal
中启动线程
void MainWindow::buttonSignal(){
thread = std::thread(foo);
}
这将创建一个临时std::thread
,将使用move assignment进行移动。
别忘了在销毁之前显式加入线程:
MainWindow::~MainWindow()
{
delete ui;
if (thread.joinable())
thread.join();
}
当然,不要忘记正确同步线程之间的所有通信。
答案 1 :(得分:0)
由于thread
方法退出后buttonSignal
变量被破坏,因此您应该从变量中分离线程。
void MainWindow::buttonSignal(){
std::thread thread (foo);
thread.detach();
}
答案 2 :(得分:0)
您还可以考虑将std :: async与lambda函数一起使用,以在单独的线程中执行次要任务。然后,您可以从中初始化一个std :: future类成员,以获取结果和通知。 另外,还有QtConcurrent框架中的QFuture和QFutureWatcher。