2017-05-08 30 views
0

현재 QTimer 구현의 threadsafety에 대해 생각하고 있습니다.QTimer의 isActive() 메소드가 스레드 안전합니까?

내 응용 프로그램에서 타이머가 실행 중인지 확인하려면 bool isActive() 메서드를 사용합니다. 이 메서드를 다른 스레드에서도 사용할 계획이므로 스레드에 대한 고려 사항을 생각해 봤습니다.

내 연구에 따르면 bool isActive() 메서드는 스레드 세이프가 아닙니다. 이 멤버 변수가 초기화된다

inline bool isActive() const { return id >= 0; } 

:

QTimer (QTimer source code)의 구현이 부재 가변 int id; 큰 0 넘으면 bool isActive() 단지 확인 것을 보여준다 : 여기서

내 가정이다 생성자는 INV_TIMER이고 이는 -1으로 정의됩니다. 타이머가 시작되면 int QObject::startTimer(int interval)의 반환 값으로 설정됩니다.

isActive()에 대한 호출이 내 의견으로는, 다른 스레드에서 QTimer::start() 동안 실행
/*! \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); 
} 

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; 

}; 
+1

QTimer는 스레드 안전하지 않으므로 재진입 중이 아닙니다. 따라서 코드의 뮤텍스조차도 안전합니다. – peppe

답변

1

는 다른 스레드에서 전화 QTimer::isActive 싶은 경우에, 당신의 솔루션은 안전 보인다. isActiveid 멤버 변수에만 액세스하므로 모든 쓰기를 mutex-protect해야합니다. id, 그리고 id은 스레드에서 읽어야합니다. isActivestop에 대해 그렇게 했으므로 모양이 좋습니다.

id에 쓰는 QTimer의 다른 메서드를 호출하면 정의되지 않은 동작이 발생합니다. 따라서 QTimer::setInterval(), QTimer::~QTimer() (!) 등의 전화를하지 않도록주의하십시오. 또한 id에 쓸 것이므로 에있는 singotsot 타이머를 사용하지 마십시오.

일반적으로 기존 클래스를 래핑하고 뮤텍스를 추가하는 것은 위험합니다.이 작업은 해당 클래스의 내부 구조에 따라 다르며 모든 경우에 대해 확인하기가 어렵습니다. 또한 내부 버전은 다음 Qt 버전에서 변경 될 수 있습니다. 다음 버전에서는 QTimer::timerEvent()이 무조건 id을 변경하며 솔루션이 더 이상 스레드 안전하지 않습니다.

귀하의 접근 방식이 작동하는 동안 일반적으로 반대하는 것이 좋습니다.