[英]Is the method 'isActive()' of QTimer threadsafe?
我目前正在考虑QTimer
实现的线程安全性。
在我的应用程序中,我使用bool isActive()
方法检查计时器是否正在运行。 当我计划在其他线程中也使用此方法时,我的想法就涉及线程安全性考虑因素。
根据我的研究, bool isActive()
方法不是线程安全的。
这是我的假设:
QTimer
的实现( QTimer源代码 )显示, bool isActive()
仅检查成员变量int id;
大于0:
inline bool isActive() const { return id >= 0; }
此成员变量在构造函数中使用INV_TIMER
初始化, INV_TIMER
是-1
的定义。 当计时器启动时,它将被设置为int QObject::startTimer(int interval)
的返回值。
/*! \overload start()
Starts or restarts the timer with the timeout specified in \l interval.
If \l singleShot is true, the timer will be activated only once.
*/
void QTimer::start()
{
if (id != INV_TIMER) // stop running timer
stop();
nulltimer = (!inter && single);
id = QObject::startTimer(inter);
}
当我从另一个线程在QTimer::start()
期间执行对isActive()
的调用时,我认为bool isActive()
的返回值可能无效。
我会感谢能够验证我的假设的人的意见。
为了达到线程安全,我只需使用互斥体将对计时器的调用包装起来,如下面的代码片段所示。
class SensorControl : public QObject
{
Q_OBJECT
public:
SensorControl(); // inits and interval-settings are done at implementation
bool Start()
{
QMutexLocker lock(&m_mutexTimer);
return m_pTimer->start();
}
void Stop()
{
QMutexLocker lock(&m_mutexTimer);
return m_pTimer->stop();
}
bool IsMeasuring() const
{
QMutexLocker lock(&m_mutexTimer);
return m_pTimer->isActive();
}
private:
QMutex m_mutexTimer;
QTimer* m_pTimer;
};
如果你想只调用QTimer::isActive
从另一个线程,那么你的解决方案看起来是安全的。 isActive
只访问id
成员变量,因此您需要互斥保护所有对id
写入以及从线程中读取id
。 您是为isActive
和stop
这样做的,所以看起来不错。
请注意,如果您曾经调用其他写入id
的QTimer
方法,则将获得未定义的行为。 因此,请注意不要调用诸如QTimer::setInterval()
, QTimer::~QTimer()
(!)之类的东西。 也不要使用Singleshot计时器,因为它将写入QTimer::timerEvent()
id
。
通常,包装一个现有的类并添加互斥体是危险的,这是否起作用取决于该类的内部,并且很难在所有情况下进行检查。 同样,内部结构可能在下一个Qt版本中发生变化,也许在下一个版本中QTimer::timerEvent()
将无条件地更改id
,并且您的解决方案不再是线程安全的。
因此,尽管您的方法可行,但总体上我还是建议不要这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.