gpt4 book ai didi

插槽断开后的 Qt 信号

转载 作者:行者123 更新时间:2023-12-04 13:24:37 27 4
gpt4 key购买 nike

我有一个来自生产者对象处理的硬件的实时数据流。这会连接到一个消费者,该消费者在自己的线程中处理它以保持 gui 响应。

mainwindow::startProcessing(){
QObject::connect(producer,SIGNAL(dataReady(data*),consumer,SLOT(doData(data*)));
consumer->moveToThread(&consumerThread);
consumerThread.start();
}

mainwindow::stopProcessing(){
producer->disconnect(SIGNAL(dataReady(data*));
consumer->cleanup();
delete consumer;
}

consumer::doData(data* x) {
mutex.lock();
processingObject stuff
mutex.unlock()
}

consumer::cleanup() {
mutex.tryLock();
.... blah ....
delete processingObject; // then doData gets called again
}

我的问题是,在我销毁消费者对象后,我仍然收到发送给它的信号,即使在断开连接之后也是如此。我已经尝试了一组越来越复杂的互斥锁来尝试阻止这种情况,但理想的解决方案是让清理等到所有未完成的信号都被处理完。

有没有办法监控有多少未处理的信号在排队等候一个插槽?或者无论如何清除它们?

最佳答案

您似乎是从与它所在的线程不同的线程中销毁使用者对象。如果在正确的线程中完成,QObject 通常会处理所有断开连接和事件队列在销毁时自行清除。来自 Qt's documentation :

Calling delete on a QObject from a thread other than the one that owns the object (or accessing the object in other ways) is unsafe, unless you guarantee that the object isn't processing events at that moment. Use QObject::deleteLater() instead, and a DeferredDelete event will be posted, which the event loop of the object's thread will eventually pick up.

只需将清理放在消费者的析构函数中,并使用 QMetaObject::invokeMethod(consumer, "deleteLater"); 让消费者从自己的线程中销毁自己。在插槽上使用 invokeMethod 将以线程安全的方式发送对 deleteLater 的调用,这似乎是必要的,因为我没有看到任何文档说 deleteLater 本身是线程安全的。如果您必须阻塞直到消费者被销毁,您可以将连接类型指定为 Qt::BlockingQueuedConnection,否则默认的 Qt::AutoConnection 应该没问题。

关于插槽断开后的 Qt 信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11766356/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com