c++ - Qt/C++ 如何在发出信号时等待一个槽

标签 c++ multithreading qt5 signals-slots

我用 Qt/C++ 开发了一个应用程序,我使用信号/槽机制在 2 个线程之间进行交互。第一个线程运行 UI/TreeWidget,第二个线程运行框架

我在一项操作上遇到了问题。

在 UI 方面,在开始我的操作之前,我在 UI 和框架之间连接信号/槽,如下面的 treewidget.cpp

connect(&m_Framework, &Framework::RequestIfNameExist, this, &TreeWidget::RequestIfNameExist);
connect(this, &TreeWidget::SendAnswerIfNameExist, &m_Framework, &Framework::NotifIfNameExist);

框架,启动并发送RequestIfNameExist:

emit RequestIfNameExist(tmpname, item, fileInfo.isDir());

while(WaitingResponse == false){
    usleep(200);
}

我添加了一个循环,因为我需要等待反馈。奇怪的是,在 treewidget.cpp 中,我从不输入

void TreeWidget::RequestIfNameExist(QString name, TreeWidgetItem *parent, bool isFolder) {
#ifdef PULS_LOG
    QLOG_INFO() << "[TreeWidget] [RequestIfNameExist] ";
#endif
    emit SendAnswerIfNameExist(isNameExist(name, parent), isFolder);
}

我从未访问过 TreeWidget 中的 RequestIfNameExist,但信号已发出。

我还在框架里放了一个while循环等待TreeWidget的反馈

void Framework::NotifIfNameExist(QTreeWidgetItem *item, bool isFolder){

    if(item != NULL)
        item->isFolder = isFolder;

    WaitingResponse = true;

}

知道为什么框架发出的信号从未到达 treewidget 吗?它是来自 while 吗??

有没有办法不使用 while 比如“等待事件”+超时

谢谢

最佳答案

我的第一个想法是,让一个线程阻塞直到另一个线程中的操作完成是一个糟糕的设计——它部分地违背了拥有多个线程的目的,即允许多个操作并行运行。如果您不小心,它也可能导致死锁(例如,如果两个线程决定大约同时发出并等待!)

更好的设计是让启动方法执行 emit RequestIfNameExit 然后立即返回,这样启动线程的事件循环可以在操作期间照常继续运行。然后,当另一个线程完成它的工作时,它通过发出自己的响应信号来响应,导致调用第一个线程中的适当/连接的槽方法,此时结果在第一个线程中处理回来。

就是说,如果您坚持要在一个方法内阻止信号发射线程的执行,直到另一个线程完成关联的槽方法的执行,您可以通过设置信号/槽连接的输入 Qt::BlockingQueuedConnection (可以通过 connect() 的可选额外参数指定连接类型)。如果你这样做,那么你发出的调用将不会返回,直到插槽方法(在另一个线程中)完成执行。鉴于此,您可以通过将指向数据对象的指针作为信号/槽方法签名中的参数之一传递并让另一个线程根据需要填充该数据对象来从另一个线程获取结果。当 emit 返回时,您只需检查该数据对象的内容即可查看结果。

关于c++ - Qt/C++ 如何在发出信号时等待一个槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30633560/

相关文章:

ios - SIGABRT线程错误运行简单的iOS应用程序

c++ - QItemSelectionModel::selectedIndexes() 崩溃

c++ - 多线程ifstream/ofstream

qml - 如何更改列或行中项目之间的间距

javascript - QWebView 类在 Qt 5.0.0 中工作吗?

c++ - 如何在自制操作系统中获取键盘输入?

c++ - QT 在错误的类中寻找插槽

c++ - QVector 项目是否共享相同的缓存行?

c++ - 在编译时检查模板参数类型是否为集合或多重集,以及容器的元素类型是否为算术

vb.net - 为什么这个多线程VB.NET(2010 Express Edition)程序不能正常工作?