Seb*_*Seb 1 c++ multithreading signals-slots qt5
我用 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);
Run Code Online (Sandbox Code Playgroud)
框架,启动并发送 RequestIfNameExist:
emit RequestIfNameExist(tmpname, item, fileInfo.isDir());
while(WaitingResponse == false){
usleep(200);
}
Run Code Online (Sandbox Code Playgroud)
我添加了一个循环,因为我需要等待反馈。奇怪的是,在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);
}
Run Code Online (Sandbox Code Playgroud)
我从不访问 TreeWidget 中的 RequestIfNameExist 但发出了信号。
我还在框架中放置了一个 while 循环以等待来自 TreeWidget 的反馈
void Framework::NotifIfNameExist(QTreeWidgetItem *item, bool isFolder){
if(item != NULL)
item->isFolder = isFolder;
WaitingResponse = true;
}
Run Code Online (Sandbox Code Playgroud)
知道为什么框架发出的信号从未到达 treewidget 吗?是从那个时候来的吗??
有没有办法不使用while,例如“等待事件”+超时
谢谢
我的第一个想法是,在另一个线程中的操作完成之前让任一线程阻塞是一种糟糕的设计——它在一定程度上违背了拥有多个线程的目的,即允许多个操作并行运行。如果您不小心,它也可能导致死锁(例如,如果两个线程决定几乎同时发出并等待!)
更好的设计是让启动方法执行emit RequestIfNameExit然后立即返回,以便启动线程的事件循环可以在操作期间照常继续运行。然后,当另一个线程完成它的工作时,它通过发出自己的响应信号来响应,导致第一个线程中的适当/连接的槽方法被调用,此时结果在第一个线程中被处理回。
也就是说,如果您坚持要阻止方法内的信号发射线程的执行,直到另一个线程完成执行关联的槽方法,您可以通过将信号/槽连接的类型设置为Qt::BlockingQueuedConnection(连接类型可以通过connect()的可选额外参数指定)。如果你这样做,那么你发出调用将不会返回,直到插槽方法(在另一个线程中)完成执行。鉴于此,您可以通过将指向数据对象的指针作为信号/槽方法签名中的参数之一传递给另一个线程,并让另一个线程根据需要填充该数据对象,从而从另一个线程获取结果。当发出返回时,您只需检查该数据对象的内容即可查看结果。