C++ 多线程调用函数崩溃:使用 Qt 信号和槽机制实现跨线程访问

在使用 C++ 多线程时,有时需要在不同的线程中调用函数,并访问主线程中的成员变量或函数。例如,在你的代码中,你试图通过函数指针 reinterpret_cast 来实现跨线程调用,但遇到了崩溃问题。

问题分析:

你遇到的问题是 reinterpret_cast 无法保证函数指针在不同线程中的正确转换。在不同的线程中,内存地址和函数地址可能不同,直接使用 reinterpret_cast 可能会导致无法访问正确的内存地址,从而导致崩溃。

解决方案:

推荐使用 Qt 的信号和槽机制来实现跨线程调用函数。这是一种安全可靠的方法,可以避免函数指针转换带来的风险。

步骤:

  1. 定义信号:

    MainWindow 类中定义一个信号,用于通知其他线程需要执行的函数:

    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    signals:
        void updataStateSignal(); // 信号名称
    };
    
  2. 连接信号和槽:

    在主线程中,连接 MainWindowupdataStateSignal 信号到 RunScript 线程的槽函数:

    MainWindow *mainWindow = new MainWindow();
    RunScript *runscript = new RunScript(mainWindow); // 将 MainWindow 对象传递给 RunScript
    connect(mainWindow, &MainWindow::updataStateSignal, runscript, &RunScript::updataStateSlot); // 连接信号和槽
    
  3. 在槽函数中调用函数:

    RunScript 线程的槽函数中,调用需要执行的函数:

    class RunScript : public QThread
    {
        Q_OBJECT
    public:
        explicit RunScript(MainWindow *mainWindow) : mainWindow(mainWindow) {}
    public slots:
        void updataStateSlot() {
            mainWindow->updataState(); // 调用 MainWindow 的函数
        }
    private:
        MainWindow *mainWindow;
    };
    
  4. 在主线程中发送信号:

    MainWindowupdataState 函数中,发送 updataStateSignal 信号:

    void MainWindow::updataState() {
        qDebug() << "123";
        emit updataStateSignal(); // 发送信号
    }
    

总结:

通过 Qt 的信号和槽机制,可以安全地实现跨线程调用函数,避免了函数指针转换带来的风险。同时,这种方法也更加清晰易懂,方便维护和扩展。

注意:

  • 确保 RunScript 线程的槽函数是 public slots 的,以便可以连接到其他线程的信号。
  • 确保 MainWindow 对象在 RunScript 线程的生命周期内有效,以防止内存泄漏。

示例:

#include <QApplication>
#include <QThread>
#include <QWidget>
#include <QDebug>

class MainWindow : public QWidget
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr) : QWidget(parent) {}
signals:
    void updataStateSignal();
public slots:
    void updataState() {
        qDebug() << "123";
        emit updataStateSignal();
    }
};

class RunScript : public QThread
{
    Q_OBJECT
public:
    explicit RunScript(MainWindow *mainWindow) : mainWindow(mainWindow) {}
public slots:
    void updataStateSlot() {
        mainWindow->updataState();
    }
private:
    MainWindow *mainWindow;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow *mainWindow = new MainWindow;
    RunScript *runscript = new RunScript(mainWindow);
    connect(mainWindow, &MainWindow::updataStateSignal, runscript, &RunScript::updataStateSlot);
    runscript->start();
    mainWindow->show();
    return a.exec();
}
C++ 多线程调用函数崩溃:使用 Qt 信号和槽机制实现跨线程访问

原文地址: https://www.cveoy.top/t/topic/nwDt 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录