我有这样的代码:
主窗h:
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
private:
QMutex mutex;
}mainwindow.cpp:
void MainWindow::on_calculateBtn_clicked() {
QMutexLocker locker(&mutex);
qDebug() << "mutex has been locked" << endl;
ui->calculateBtn->setEnabled(false);
startProcess(); // huge calcutations
ui->calculateBtn->setEnabled(true); // performed before startProcess() has finished (why?)
qDebug() << "mutex will be unlocked" << endl;
}如果在calculateBtn ()尚未完成时再次单击startProcess,则程序崩溃:
pure virtual method called
The program has unexpectedly finished.我试过:
void MainWindow::on_calculateBtn_clicked() {
if (!processing) {
processing = true;
ui->calculateBtn->setEnabled(false);
startProcess();
ui->calculateBtn->setEnabled(true); // performed before startProcess() has finished (why?)
processing = false;
}
}没有共享数据,我只希望在其他startProcess()完成之前不会启动一个startProcess()。为什么会这样呢?我认为互斥锁必须将函数startProcess()锁定在on_calculateBtn_clicked()中,不应该发生任何事情。看来我不知道什么重要的事。事先谢谢您的建议。
发布于 2016-03-06 23:02:23
同一个互斥锁从同一个线程(包含事件循环的主线程)锁定两次,对非递归互斥无效。
但是,即使是递归互斥也不能解决代码的基本问题;您需要一个标志来指示您已经在进行计算,并在方法运行时从所有后续调用返回,否则您将在同一个线程中多次启动它们,其中一个中断另一个线程,可能结果很糟糕。更好的是,在该方法运行时禁用按钮,并注意其他方法不会调用它。
但是,如果多次调用startProcess()并同时运行它,则必须为每个按下按钮启动一个线程,而要小心访问共享数据(很可能是使用互斥)--这才是真正的乐趣之源。
发布于 2016-03-07 07:46:42
我认为您(默认情况下)有一个Qt::DirectConnection与此按钮按下,对吗?即:
connect(..., SIGNAL(...),
..., SLOT(:on_calculateBtn_clicked()), <by-default-Qt::DirectConnection>);我在这里看到的问题是,第一个按钮将立即运行函数void MainWindow::on_calculateBtn_clicked() .到目前为止,这一切都很好,互斥锁上了,巨大的计算机正在运行。
但是,当您再次按下按钮时,void MainWindow::on_calculateBtn_clicked()再次立即运行(就像中断一样)。它所做的第一件事就是试图锁定互斥锁,它必须挂在这里。
如果连接到时隙void MainWindow::on_calculateBtn_clicked() Qt::QueuedConnection,那么在清除任务队列中的其他任务之前,它不会触发按下按钮。
但是..。天气是否好你的设计是好的是值得怀疑的,我认为你应该重新考虑你的策略(正如一些评论所建议的)。
编辑
哦,是的,意思是.为了回答你的问题,所以我不认为互斥开始两次解锁.这正是直接联系的本质。
https://stackoverflow.com/questions/35833122
复制相似问题