2017-05-08 11 views
0

私は現在QTimer実装のスレッドセーフについて考えています。私のアプリケーションでQTimerのisActive()メソッドはスレッドセーフですか?

私はタイマーが作動しているかどうかチェックするためにbool isActive()メソッドを使用します。このメソッドを他のスレッドからも使用する予定であるため、私の考えはスレッドセーフに対する考慮事項になりました。

は、私の研究によれば、この方法bool isActive()はスレッドセーフではありません。ここで

は私の仮定です:

QTimerQTimer source code)の実装では、メンバー変数int id;が0より大きい場合bool isActive()はちょうどチェックしていることを示しています。

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

このメンバ変数がで初期化されます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はスレッドセーフではなく、リエントラントでもありません。あなたのコードのmutexでさえ、安全にすることはできません。 – peppe

答えて

1

あなたが別のスレッドからのみコールQTimer::isActiveにしたい場合は、あなたのソリューションは安全に見えます。 isActiveはメンバー変数idにのみアクセスするため、すべての書き込みをidにミューテックスで保護する必要があり、スレッドからidを読み取る必要があります。あなたはisActivestopのためにそれをしたので、それは良いですね。

idに書き込むQTimerの他のメソッドを呼び出すと、未定義の動作が発生することに注意してください。したがって、QTimer::setInterval()QTimer::~QTimer()(!)のようなものを呼び出さないように注意してください。また、idQTimer::timerEvent()で書き込むので、単体タイマを使用しないでください。

既存のクラスの一般的なラッピングにしてミューテックスを追加するには、その作品が言ったクラスの内部に依存し、それらはすべてのケースをチェックするのは難しいですか、危険です。また、内部バージョンは次のQtバージョンで変更される可能性があります。QTimer::timerEvent()は無条件でidを変更し、あなたのソリューションはもはやスレッドセーフではありません。

あなたのアプローチがうまくいく間、一般的に私はそれに対してお勧めします。

関連する問題