2017-06-28 9 views
0

私は1つの原子変数(bool)とその変数をポーリングする別のスレッドを変更するスレッドを持っています。私のアプリケーションでは、thread Aで関数呼び出しがほとんどなく、特定の1つの原子変数でポーリングを開始します。 Thread Bは、一部の外部アプリケーション(application on dbus)のステータスを読み続けるため、それに応じて少数のアトミック変数を変更します。 Thread Aの関数は、戻り値がある場合、外部アプリケーションが状態を希望の状態に変更して、これらのアトミックフラグを介して知るようにしたいと考えています。私のアプリケーションのC++の原子変数(bool)のポーリング?

詳細:

機能thread Adbus APIを使用して近くのBLEデバイスのスキャンを開始start_scan()機能です。ただし、start scan呼び出しが成功したにもかかわらず、外部アプリケーション(org.bluez)がプロパティ(Property: Discovering)の更新に少し時間がかかります。私はまた、外部アプリケーションの現在の状態についていくつかの変数(私のアプリケーションの内部)を照会するisScanningのような関数を定義しました。外部アプリケーションのプロパティが更新されると、PropertiesChangedシグナルを介してdbusに通知され、はい、start_scanへの呼び出しが成功した後、スキャンのためにPropertiesChangedシグナルを受信するまでに時間がかかります(1秒未満)。だから、start_scan関数から戻る前に自分のローカルアトミックフラグを(自分のタイムアウト機構で)ポーリングすることを考えています。が有効な状態を返します。

synの中に必要な多くの関数とフラグがあるので、私はcondition_variableを使用できません。

問題:スレッドAがscanning_フラグのポーリングされるときに、スレッドBがscanning_フラグを更新するdbus信号を受信する

std::atomic<bool> scanning_; 

// Thread A 
void start_scan() 
{ 
    // Dbus methods call 
    while (scanning_ == false) { // With some timeout 
     // Timeout mechanism 
    } 
} 

// Thread B receving asyn signals from DBus 
void propertyUpdate(std::string name, bool value) 
{ 
    if (name == "Discovering") 
     scanning_ = value; 

    ... 
} 

。私はThread AがスレッドBを絶えず旗を読んでいて、私の旗が原子的であるかのようにチョークするかどうか分からないのですか?原子変数が利用可能になると、スレッドが原子変数アクセスを待つスレッドがどのようにスケジュールされているかを知りたいですか?

EDIT:

が、私はこのような何かをしています:

void setter(bool value) 
    { 
     std::lock_guard<std::mutex lock(mutex_); 
     member_ = value; 
    } 

    bool getter(void) 
    { 
     std::lock_guard<std::mutex lock(mutex_); 
     return member_; 
    } 

    // Thread A is blocking on a class member value 
    while (getter() == false); 

    // Thread B will modify the class member when required 
    setter(true); 

は私があるため、共通のミューテックスでブロックされたスレッドのスケジューリングの顔可能性のある問題を知ってほしいです。スレッドAがmutex_を取得し続ける可能性はありますが、スレッドBは永遠にブロックされます。スレッドAが返された後、スレッドAが再びmutex_を取得する前に、スレッドBがgetter関数の復帰後にスケジュールされていない場合に発生する可能性があります。

+0

ミューテックスやセマフォーを使用できませんでしたか? – rcgldr

+0

ポーリングはリソースの無駄であり、標準ではそれが動作することを保証するものではありません。条件変数を使用します。 –

+0

@ n.m .:私のスレッドが他のスレッドによって変更された変数をポーリングすると、私のスレッドは更新を見ないでしょうか? – abhiarora

答えて

3

条件が成立するまでスレッドをブロックする必要がある場合は、にタイムアウトを指定してcondition variablesを使用してください。このようにして、scanning_は、通常の変数であり、原子的な変数ではなく、mutexによって保護されます。

(いくつかのスレッド通信には原子変数を使用できますが、アトム変数を使用するだけでスレッドをスリープさせることはできません。あなたの例では、start_scanは常に実行され、CPU時間を消費します)

+0

はい、私はポーリング用の変数がいくつかあり、各フラグに条件変数を作成したくありません。 – abhiarora

+0

私は自分の質問を更新しました。 – abhiarora

+0

現在、更新された投稿を読む時間がありません。あなたのコメントに返信します。複数のコンデバーを作成する必要はありません。 **フラグの** **が変更されたら、condvar.signal()を呼び出す必要があります。次に、もう一方のスレッドでは、condvar.wait()が戻った後、フラグの値をチェックできます。申し訳ありませんこの方法を使用できない場合は、後で投稿を読んでいます。 – geza

関連する問題