【发布时间】:2019-02-12 14:31:29
【问题描述】:
从另一个线程向对象发出信号是否安全(如果插槽连接为QueuedConnection)?我找不到会提到这一点的特定文档,我找到的最多的 relevant quote 是这样的:
QObject 是可重入的。它的大部分非 GUI 子类,例如 QTimer, QTcpSocket、QUdpSocket 和 QProcess,也是可重入的,使得它 可以同时从多个线程使用这些类。 请注意,这些类旨在从以下位置创建和使用 在一个线程内; 在一个线程中创建一个对象并调用 不保证它在另一个线程中的功能可以正常工作。
这表明它可能不行,这也适用于信号吗? QMetaObject::activate 里面有一个QMutexLocker,所以在我看来它可能是线程安全的......?
#include <QCoreApplication>
#include <QTimer>
#include <thread>
#include <iostream>
struct Foo : public QObject
{
Q_OBJECT
public:
Foo(QObject* parent) : QObject(parent) {}
public slots:
void run()
{
connect(this, &Foo::signal, this, [] { std::cout << "activated"; }, Qt::QueuedConnection);
std::thread t([this] { emit signal(); });
if (t.joinable()) t.join();
}
signals:
void signal() const;
};
#include "main.moc"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Foo* b = new Foo(&a);
QTimer::singleShot(0, b, &Foo::run);
return a.exec();
}
【问题讨论】:
-
Qt 在Signals and Slots Across Threads 上的文档怎么样?
-
@AMA:它只提到了发送者和接收者生活在不同线程中的情况,但这是一个不同的问题......我问的是从线程中调用对象没有的信号'住在里面。
-
@Jaa-c 对象所在的位置并不重要。从另一个线程发出信号是安全的。
标签: c++ multithreading qt thread-safety qt-signals