簡體   English   中英

使用多個線程時,Qt Creator崩潰

[英]Qt Creator crashes when using multiple threads

我正在編寫Qt(5.3)程序,其中包含操縱桿測試UI,但是我需要一個單獨的線程用於無限while循環,以通過SDL查找操縱桿軸/按鈕值更改。 代碼的這一部分工作正常,因為我可以使用線程qDebug()消息,並且似乎可以正常工作。 但是從主窗口中,當我嘗試打開測試操縱桿UI時,程序崩潰了。 我已經在沒有JoystickThread線程的情況下使測試操縱桿UI運行分離,並且似乎可以正常運行。

錯誤消息雖然不一致-有時,我只是得到

該程序意外完成。 / home / narendran / QtWorkspace / build-LinkControl-Desktop-Debug / LinkControl崩潰

這已經出現一次:

QXcbWindow:未處理的客戶端消息:“ _ GTK_LOAD_ICONTHEMES”

還有其他幾次:

[xcb]處理隊列時未知的序列號[xcb]這很可能是多線程客戶端,尚未將XInitThreads稱為[xcb]正在中止,對此感到抱歉。 星號:../../src/xcb_io.c:274:poll_for_event:斷言`!xcb_xlib_threads_sequence_lost'失敗。

我發現如果XInitThreads();這很常見。 不是在主函數中運行,但是即使在主函數上運行,它也因相同的錯誤而崩潰。

main.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-枚舉

某些元素只能從“ GUI”線程或程序的主線程訪問。 這是具有QApplication::exec();的線程QApplication::exec(); 繼續 它具有一個事件循環,可以傳播消息。

查看應用程序輸出中Qt會告訴您的運行時錯誤。

跨越線程邊界時,請確保使用信號和插槽。

而且,如果您要從該線程外部訪問線程類的成員,請確保使用線程同步的做法,例如,使用QMutexLocker locker(m_mutex);前綴對這些成員的所有訪問QMutexLocker locker(m_mutex);

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

正如標題“ GUI線程”所暗示的那樣,它是唯一允許做某些事情的線程,例如繪制QPixmap和訪問QWidget的某些部分。

希望能有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM