“如何修复”;在Qt两定时器对一功能中,使用qmutex将qeventloop用于睡眠;
我有一些代码使用qtcpsocket来写和读, 写入-->睡眠-->读取; 用户界面有2个或更多的定时器来使用此功能;通过我想我运行同步;所以我添加了互斥锁来锁定它;由此产生僵局 qt4;qt5“如何修复”;在Qt两定时器对一功能中,使用qmutex将qeventloop用于睡眠;,qt,timer,deadlock,qeventloop,qmutex,Qt,Timer,Deadlock,Qeventloop,Qmutex,我有一些代码使用qtcpsocket来写和读, 写入-->睡眠-->读取; 用户界面有2个或更多的定时器来使用此功能;通过我想我运行同步;所以我添加了互斥锁来锁定它;由此产生僵局 qt4;qt5 void MainWindow::Start() { pTimer = new QTimer(this); pTimer->setInterval(100); connect(pTimer,SIGNAL(timeout()), this, SLOT(OnTimer()) )
void MainWindow::Start()
{
pTimer = new QTimer(this);
pTimer->setInterval(100);
connect(pTimer,SIGNAL(timeout()), this, SLOT(OnTimer()) );
pTimer->start();
pTimer2 = new QTimer(this);
pTimer2->setInterval(100);
connect(pTimer2,SIGNAL(timeout()), this, SLOT(OnTimer()) );
pTimer2->start();
}
void MainWindow::OnTimer()
{
FunCal(); // in my real code it will MyObj.DoSometing();
}
void MainWindow::FunCal()
{
qDebug()<<"log in fun...";
QMutexLocker loc(&this->_mtx);
qDebug()<<"getted lock in fun...";
QEventLoop loop;
QTimer::singleShot(100, &loop, SLOT(quit()));
loop.exec();
qDebug()<<"log out fun...";
}
void主窗口::Start()
{
pTimer=新的QTimer(本);
pTimer->setInterval(100);
连接(pTimer,信号(timeout()),此,插槽(OnTimer());
pTimer->start();
pTimer2=新的QTimer(本);
pTimer2->设置间隔(100);
连接(pTimer2,信号(timeout()),此,插槽(OnTimer());
pTimer2->start();
}
void主窗口::OnTimer()
{
FunCal();//在我的实际代码中,它将是MyObj.DoSometing();
}
void主窗口::functal()
{
qDebug()imop的问题是由一个基本的误解引起的:
QTimer
不引入多线程。
它只是一种将特定时间后发送的事件排队的工具。
这就是为什么必须使用QEventLoop
才能使其运行
但是,它仍然是一个确定性执行,这可能是OP代码中发生的情况:
pTimer->start();
→ 启动第一个计时器
pTimer2->start();
→ 启动第二个计时器
- 控制流返回到
QApplication
的事件循环(未在代码中公开)
- 第一个计时器到期并调用
MainWindow::FunCal()
qDebug()\u mtx
被锁定
qDebug()imop问题是由基本误解引起的:
QTimer
不引入多线程。
它只是一种将特定时间后发送的事件排队的工具。
这就是为什么必须使用QEventLoop
才能使其运行
但是,它仍然是一个确定性执行,这可能是OP代码中发生的情况:
pTimer->start();
→ 启动第一个计时器
pTimer2->start();
→ 启动第二个计时器
- 控制流返回到
QApplication
的事件循环(未在代码中公开)
- 第一个计时器到期并调用
MainWindow::FunCal()
qDebug()\u mtx
被锁定
qDebug()它的运行方式类似于“登录乐趣…”;“getted lock in fun…”;“log in fun…”您的问题不是很清楚。是否要同步函数FunCal()
,以便一次最多执行一次?它的运行方式类似于“log in fun…”;“getted lock in fun…”;“log in fun…”;你的问题不太清楚。你想同步函数FunCal()
,以便一次最多执行一次吗?@danny实际上,我的回答描述了你做错了什么,但没有解释如何做对。那是因为我在你的问题中没有认识到你的实际问题(您实际试图解决的问题)。我假设您希望基于某个计时实现一系列操作。我将使用状态的整数变量来完成此操作。超时:根据状态执行操作,设置下一个状态,重新启动计时器(可能间隔不同),并从信号处理程序返回。本质上,信号处理程序在处理后立即返回。否则,事件循环就会停止。@danny实际上,我的回答描述了你做错了什么,但没有解释如何做对。这是因为我无法在你的问题中认识到你的实际问题(您实际试图解决的问题)。我假设您希望基于某个计时实现一系列操作。我将使用状态的整数变量来完成此操作。超时:根据状态执行操作,设置下一个状态,重新启动计时器(可能间隔不同),并从信号处理程序返回。本质上,信号处理程序在处理后立即返回。否则,事件循环将暂停。
QApplication::exec()
QEventLoop::exec()
QEventLoop::processEvents()
QTimer::timerEvent()
QTimer::timeOut()
MainWindow::onTimer()
MainWindow::FunCal()
QEventLoop::exec()
QTimer::timerEvent()
QTimer::timeOut()
MainWindow::onTimer()
MainWindow::FunCal()
QMutexLocker::QMutexLocker()
QMutex::lock()
#include <iostream>
#include <mutex>
#include <functional>
#include <cassert>
// a lock class
class Lock {
private:
bool _lock;
public:
Lock(): _lock(false) { }
~Lock() = default;
Lock(const Lock&) = delete;
Lock& operator=(const Lock&) = delete;
operator bool() const { return _lock; }
void lock() { assert(!_lock); _lock = true; }
void unlock() { assert(_lock); _lock = false; }
};
// a sample data class with a property
class Object {
private:
bool _value; // a value
Lock _lockValue; // a lock to prevent recursion
public:
std::function<void()> sigValueSet;
public:
Object(): _value(false) { }
bool value() const { return _value; }
void setValue(bool value)
{
if (_lockValue) return;
std::lock_guard<Lock> lock(_lockValue);
// assign value
_value = value;
// emit signal
if (sigValueSet) sigValueSet();
}
};
#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__
int main()
{
DEBUG(Object obj);
std::cout << "obj.value(): " << obj.value() << '\n';
DEBUG(obj.sigValueSet = [&](){ obj.setValue(obj.value()); });
DEBUG(obj.setValue(true));
std::cout << "obj.value(): " << obj.value() << '\n';
}