jpo*_*o38 5 qt multithreading signals-slots
这是Qt信号/插槽连接的工作方式:
还有一个实际上是默认值的附加值:自动连接如果信号在接收对象具有亲和力的线程中发出,则其行为与直接连接相同。否则,行为与排队连接相同。”
在大多数情况下,默认设置可以正常运行:
但是,从线程发出信号时,您有两个选项来处理它:“已排队”或“阻止已排队”连接。
为什么没有这样的模式:
因为,正如文档所提到的,在同一线程中使用阻塞队列连接会导致死锁....所以处理起来确实很痛苦,我经常不得不在我的代码中创建和管理两个信号和连接来处理:
class A
{
Q_OBJECT
public:
A()
{
connect( this, SIGNAL(changedFromThread()), this, SLOT(update()), Qt::BlockingQueuedConnection );
connect( this, SIGNAL(changedNotFromThread()), this, SLOT(update()) );
}
void notifySomethingChanged()
{
if ( QObject().thread() != thread() )
emit changedFromThread(); // would dead-lock if in same thread
else
emit changedNotFromThread();
}
public slots:
void update()
{
// Do some changes to A that cannot be done from a worker thread
}
signals:
void changedFromThread();
void changedNotFromThread();
};
Run Code Online (Sandbox Code Playgroud)
如果有这种模式(Qt::AutoBlockingConnection可以调用它),我可能会写:
class A
{
Q_OBJECT
public:
A()
{
connect( this, SIGNAL(changedFromThread()), this, SLOT(update()), Qt::AutoBlockingConnection );
}
void notifySomethingChanged()
{
emit changedFromThread(); // would dead-lock if in same thread
}
public slots:
void update()
{
// Do some changes to A that cannot be done from a worker thread
}
signals:
void changedFromThread();
};
Run Code Online (Sandbox Code Playgroud)
有没有什么好的理由螺纹型连接只发给之间交换Qt::DirectConnection和Qt::QueuedConnection,但没有之间的交换Qt::DirectConnection和Qt::BlockingQueuedConnection?
小智 0
我猜 Qt 开发团队根本不希望您指定连接类型。我可以理解这种设计,从某种意义上说,几乎应该总是避免故意阻塞,如果您阻塞 UI 线程,则更是如此。
如果您希望同步QObject不同线程中的两个线程,请在两个线程中使用信号和槽,并相应地连接它们。
但是,如果您处于主从场景(通常QMainWindow拥有QObjectwith QObject::moveToThread(new QThread)),您可以:
QObject您的信号QMainWindowQObject使用QMetaObject::invokeMethodinto
调用槽QMainWindow,因此方法调用由QObject线程异步处理。