c++ - 线程上的 Qt 信号槽,这是安全的方法吗?

标签 c++ multithreading qt qtcore qt-signals

比如说,我有 2 个线程:A 和 B,A 是主线程。在线程 A 中,有两个 on_button_click 插槽。第一个是:

on_button_one_clicked(){
  myObject_one = new myObject(this);
  myObject_one->setParent(map);
  myObject_two = new myObject(this);
  myObject_two->setParent(map);
  ...
}

第二个是:

on_button_two_clicked(){
  foreach(myObject* i, map->childItems){
    delete i;
  }
}

这里,myObjectmap 都是QGraphicsItem。在线程 B 中,发出信号以触发线程 A 的槽:

slot_triggered_by_signal_from_thread_B(){
  foreach(myObject* i, map->childItems){
    i->do_some_thing();
  }
}

这样安全吗?当代码到达 i->do_some_thing 行并遇到一个空指针并崩溃时,它会发生吗?

最佳答案

只要您在线程之间使用自动连接或排队连接类型就是安全的,因为只有当您的另一个插槽完成时才会调用插槽,反之亦然。它们不会“同时”运行。这是我能想象到的唯一担心,因为它不够安全。我相信你的意思是这样的场景:

main.cpp

#include <QThread>
#include <QApplication>
#include <QTimer>
#include <QObject>
#include <QPushButton>
#include <QDebug>

class Work : public QObject
{
    Q_OBJECT
    public:
        explicit Work(QObject *parent = Q_NULLPTR) : QObject(parent) { QTimer::singleShot(200, this, SLOT(mySlot())); }
    public slots:
        void mySlot() { emit mySignal(); }
    signals:
        void mySignal();
};

class MyApplication : public QApplication
{
    Q_OBJECT
    public:

    explicit MyApplication(int argc, char **argv)
        : QApplication(argc, argv)
        , pushButton(new QPushButton())
    {
        QStringList stringList{"foo", "bar", "baz"};
        QThread *workerThread = new QThread();

        Work *work = new Work();
        work->moveToThread(workerThread);

        connect(pushButton, &QPushButton::clicked, [&stringList] () {
            for (int i = 0; i < stringList.size(); ++i)
                stringList.removeAt(i);
        });
        connect(work, &Work::mySignal, [&stringList] () {
            for (int i = 0; i < stringList.size(); ++i)
                qDebug() << stringList.at(i);           
        });
    }

    ~MyApplication()
    {
        delete pushButton;
    }

    QPushButton *pushButton;
};

#include "main.moc"

int main(int argc, char **argv)
{
    MyApplication application(argc, argv);   
    return application.exec();
}

主程序

TEMPLATE = app
TARGET = main
QT += widgets
CONFIG += c++11
SOURCES += main.cpp

构建并运行

qmake && make && ./main

关于c++ - 线程上的 Qt 信号槽,这是安全的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27330315/

相关文章:

c++ - 使用 C++ Hook QT 应用程序以捕获应用程序的文本名称

c++ - 使用 boost 库收听 udp 广播

java - 单例中的双重检查锁定

python - PySide Qt 在叶项中插入行并更新 View

java - 将任务从 EDT 分派(dispatch)到 main?

c# - 同步事件

c++ - 为什么我的小部件不显示?

c++ - 使用#define 进行库配置

c++ - 在 C++ 中循环遍历字符串

Java程序Opencv unsatisfiedlinkerror