В настоящее время я думаю о потокобезопасности реализации QTimer
.
В моем приложении я использую метод bool isActive()
, чтобы проверить, работает ли таймер или нет. Поскольку я планирую использовать этот метод и в других потоках, мои мысли перешли к соображениям безопасности потоков.
Согласно моим исследованиям, метод bool isActive()
не является потокобезопасным.
Вот мои предположения:
Реализация QTimer
(исходный код QTimer code) показывает, что bool isActive()
просто проверяет, больше ли значение переменной-члена int id;
0:
inline bool isActive() const { return id >= 0; }
Эта переменная-член инициализируется в конструкторе с помощью 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);
}
Когда вызов isActive()
выполняется во время QTimer::start()
из другого потока, на мой взгляд, возвращаемое значение 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;
};