c++ - 使用多线程时 Qt Creator 崩溃

标签 c++ multithreading qt crash x11

我正在编写一个 Qt (5.3) 程序,其中有一个操纵杆测试 UI,但我需要一个单独的线程来进行无限 while 循环,通过 SDL 查找操纵杆轴/按钮值的变化。这部分代码工作正常,因为我可以拥有线程 qDebug() 消息,并且它似乎工作正常。但是从主窗口中,当我尝试打开测试操纵杆 UI 时,程序崩溃了。我已经让测试操纵杆 UI 在没有 JoystickThread 线程的情况下运行分离,并且它似乎打开得很好。

尽管错误消息不一致 - 有时,我只是得到

The program has unexpectedly finished. /home/narendran/QtWorkspace/build-LinkControl-Desktop-Debug/LinkControl crashed

这已经出现过一次:

QXcbWindow: Unhandled client message: "_GTK_LOAD_ICONTHEMES"

还有其他几次:

[xcb] Unknown sequence number while processing queue [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. star: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.

我发现这很常见 if XInitThreads();不在主函数中运行,但即使在那里运行,它也会因相同的错误而崩溃。

ma​​in.cpp

#include <qsplashscreen.h>
#include "linkcontrol.h"
#include "configure.h"
#include <unistd.h>
#include <QApplication>
#include <QPixmap>
#include <QStyle>
#include <QDesktopWidget>
#include "linkports.h"
#include "joystickthread.h"
#include <X11/Xlib.h>

int main(int argc, char *argv[])
{
    XInitThreads();
    QApplication a(argc, argv);

    QPixmap pix(":splash.png");

    QSplashScreen splash(pix);
    splash.show();

    a.processEvents();

    JoystickThread jsThread;
    jsThread.start();

    LinkControl linkcontrol;
    usleep(1000000);
    splash.finish(&linkcontrol);
    usleep(100000);
    linkcontrol.show();

    linkcontrol.setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,linkcontrol.size(),a.desktop()->availableGeometry()));

    return a.exec();
}

实际线程位于joystickthread.cpp

#include "joystickthread.h"
#include "global.h"
#include "unistd.h"

/* JoystickThread::JoystickThread(int _interval)
{
    this->interval_us = _interval;
} */

void JoystickThread::run()
{
    while(1)
    {
        if(joystick->connected)
        {
            joystick->updateJSData();
            // Check for changed values
            for(int i=0; i<joystick->axis.count(); i++)
            {
                if(joystick->axis.value(i) != joystick->axis_last[i])
                {
                    joystick->axisUpdateEmit(i);
                    // qDebug() << "AXIS: " << i << "\tVALUE: " << joystick->axis.value(i);
                }
                joystick->axis_last[i] = joystick->axis.value(i);
            }
            for(int i=0; i<joystick->button.count(); i++)
            {
                if(joystick->button.value(i) != joystick->button_last[i])
                {
                    joystick->btnUpdateEmit(i);
                    // qDebug() << "BUTTON: " << i << "\tVALUE: " << joystick->button.value(i);
                }
                joystick->button_last[i] = joystick->button.value(i);
            }
        }
        usleep(2500);
    }
}

导致程序崩溃的函数在linkcontrol.cpp

void LinkControl::on_actionJoystick_Test_triggered()
{
    qDebug() << "STARTING CHECK";
    if(!js_test->initialized) {
        qDebug() << "NOT INIT";
        js_test = new TestJoystick();
        js_test->initialized = true;
         qDebug() << "FININSH INIT";
    }
    if(joystick->connected) {
         qDebug() << "SHOWING UI";
        js_test->show();
    } else {
        QMessageBox::critical(this, tr("No Joystick Connected!"), tr("Please connect a joystick first..."));
    }
}

其中 js_testlinkcontrol.h 文件中声明为 TestJoystick 对象

public:
    explicit LinkControl(QWidget *parent = 0);
    QSlider *portSliders[16];
    QLineEdit *setVals[16];
    SerialTerminal *ser_term;
    TestJoystick *js_test;
    ~LinkControl();

非常感谢!如果您需要更多信息,请告诉我。

最佳答案

QThread 最初有点难以适应,并且也有一些陷阱。

您应该在运行函数的顶部构建并连接适当的项目。

如果您在其他地方执行此操作,则需要确保不使用 Qt::AutoConnection,而是使用 Qt:QueuedConnection

http://qt-project.org/doc/qt-5/qt.html#ConnectionType-enum

某些元素只能从“GUI”线程或程序的主线程访问。这是运行 QApplication::exec(); 的线程。它有一个事件循环来传播消息。

查看应用程序输出中 Qt 会告诉您的运行时错误。

当跨越线程边界时,一定要使用信号和槽。

如果您要从该线程外部访问线程类的成员,请务必使用线程同步实践,例如在对这些成员的所有访问之前使用QMutexLocker locker(m_mutex); .

http://qt-project.org/doc/qt-5/threads.html

正如标题“GUI线程”所暗示的那样,它是唯一允许执行某些操作的线程,例如绘制QPixmap和访问QWidget的某些部分>s.

希望有帮助。

关于c++ - 使用多线程时 Qt Creator 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26195828/

相关文章:

c++ - 具有通用类型函数的动态库 [c++]

multithreading - 在Windows中使用事件同步线程

c# - 我使用 HttpClient 的 GET 请求循环陷入了 AggregateExceptions 的神秘困惑中

c++ - 为标准 C++ 类型定义 NULL/Empty 值

c++ - py.test 与非 python 测试(具体来说,与 cxxtest)

C++ 递减单字节( volatile )数组的元素不是原子的!为什么? (还有 : how do I force atomicity in Atmel AVR mcus/Arduino)

c# - 以并行和顺序方式执行 N 个线程

c++ - 在 exec() 之前将 quit() 发布到 QEventLoop

c++ - 指针数据类型变量如何包含对象?

c++ - 使枚举调试器感知的宏?