如何在Qt的主事件循环中使用std::thread?

How to use std::thread with Qt's main event loop?

本文关键字:std thread 循环 Qt 事件      更新时间:2023-10-16

在此代码中Qt部分(fun1())总是崩溃。它写:

terminate called without an active exception
Aborted (core dumped)

怎么了?当我在main中调用Qt时,我不使用线程,它工作得很好,但我需要调用另一个函数并使用线程(fun2()只是为了说明)我的代码在这里:

#include "../common/main_window.hpp"
#include <QtGui/QApplication>
#include <QtGui>
#include <thread>
#include <iostream>
int argc_;
char **argv_;
void fun1()
{
    QApplication a(argc_,argv_);
    MainWindow w;
    w.show();
    a.exec();
}
void fun2()
{
    std::cout << "Print something" << std::endl;
}
int main(int argc, char **argv)
{
    //argc_ = malloc((1)*sizeof(char*));
    argc_= argc;
    argv_= argv;
    std::thread first(fun1);
    std::thread second(fun2);
    return 0;
}

主线程

Qt不支持在主线程之外的任何线程中运行GUI事件循环。你所做的事情恰好可以在Windows上工作,并且可能在某些unix上工作,但它永远不会在OS X或iOS上工作,例如。因此,在产品代码中,没有地方可以像现在这样运行线程。

fun1()应该从main调用,并且必须等待另一个线程的函子完成后才能销毁该线程。

int fun1(int & argc, char ** argv)
{
  // QApplication might modify argc, and this should be fed back to
  // the caller.
  QApplication a(argc, argv);
  MainWindow w;
  w.show();
  return a.exec();
}
int main(int argc, char **argv)
{
  std::thread worker(fun2);
  int rc = fun1(argc, argv);
  worker.join();
  return rc;
}

包括问题

绝不包括通过<QtModule/Class>。这将隐藏项目文件中的配置错误。你应该一个一个地包含单个类,或者一次包含整个模块的声明。

因此,您的测试用例应该具有以下两种包含样式之一:
#include <QtGui> // Qt 4 only
#include <QtWidgets> // Qt 5 only

#include <QApplication> // Qt 4/5
#include <Q....> // etc.

程序崩溃的实际原因是,如果线程既没有连接也没有分离,std::thread会在其析构函数中抛出异常。

为了避免崩溃,您需要连接两个线程。

main函数在创建线程后返回,导致程序退出并终止所有正在运行的线程。在两个线程上调用join,这样main函数在线程自己终止之前不会返回。