2017-05-25 43 views
0

以下は、50msごとに呼び出されるコールバック時に2つの変数が更新される私のコードです。 50ミリ秒ごとに目を覚まし、変数を読み込むリーダースレッドもあります。同時読み込み書き込み

thisを実行した後、コールバックが受信されたときに読み込みスレッドが起動し、読み書き中に同じmutexをロックしていないためにスレッドが起動する場合があると推測しました。一貫性のないメモリが読み取られます。

ただし、実行すると、このシナリオは発生しません。私はそれを十分長く走らせていないのですか、私の理解に間違いがありますか?二つ以上のスレッドの少なくとも一方は、1つ以上のスレッドが不整合な状態が発生する可能性が書き込み動作である共有データにアクセスしているとき

recursive_mutex mutex1 
recursive_mutex mutex2 
var1, var2 

//called every 50ms 
onUpdateListener() { 
    lock(mutex1) 
    update var1 
    update var2 
} 

VarReaderThread::readVar() { 
    sleep(50) 
    while(true) { 
     { 
     lock(mutex2) 
     read var1 
     read var2 
     sleep(50) 
     } 
    } 
} 
+0

あなたのmutexの 'スコープ'は明確ではありません。 –

+1

これらのミューテックスを使用する理由は何ですか? varsにアクセスする他のコードはありますか?このシナリオでは、彼らはまったく役に立たないからです。 –

+0

同時に書いたり読んだりしないでください。矛盾した状態(競合状態)に遭遇することがあります。読書と読書を同時に行うことはできますが、同時に書くことと書いてはいけません。書き込みは混在しません。読み取りと書き込みに別々のロックを使用することは役に立ちません。 @HenkHoltermanはそのコードでこれらのmutexが何もしていないことを示唆しています。 – Persixty

答えて

0

データ競合が発生します。

提供されているコードには、読み込み用と書き込み用の2つのミューテックスがあります。 これは、共有データ(例ではvar1var2)の読み込みをスレッドが排除することは決してありません。別のスレッドが書き込みを開始した後、またはどちらか一方に書き込みを開始した後で、もう一方の書き込みを完了する前にその中間状態は、コードロジックのパラメータおよびその目的の中で不整合な状態とみなされる。

読み取りと書き込みを排他的にするためには、mutexが必要です。 なぜ、再帰的なミューテックスが宣言されたのかは明らかではありません。これは、特定のスレッドが既に保持しているミューテックスを取得するように要求するコードに遭遇する場合にのみ必要となります。可能な限りその状況を設計し、コード化する方が良い設計です。

明示unlockステップは、または符号化モデル(等C++またはJavaで​​又はfinallystd::lock_guardを使用し、Cで要求)に応じて明示的に要求してもしなくてもよいが導入されてきました。

いくつかの条件は、適切な終了条件を示すために導入されています。 while(true)は、それ以外の条件が正常に終了しない限り、悪い習慣です。

より洗練されたモデルは、複数のスレッドが '読み取り'モードでそれを保持できる「共有ミューテックス」を使用することができますが、「書き込み」モードで保持している場合は1つのみです。それは、「書き込み」が多くの読者が無限に「書き込み」アクセスをブロックするライブロックに入らないことを確認するために、何らかのシグナリングを必要とすることも、必要としないこともあります。

mutex mutex_v1_v2 //The mutex controlling shared state var1, var2. 
var1, var2 

//called every 50ms 
onUpdateListener() { 
    lock(mutex_v1_v2) 
    update var1 
    update var2 
    unlock(mutex_v1_v2) 
} 

VarReaderThread::readVar() { 
    sleep(50) 
    while(!finished) { 
     lock(mutex_v1_v2) 
     read var1 
     read var2 
     unlock(mutex_v1_v2) 
     sleep(50) //V. V. important to sleep not holding the mutex! 
    } 
} 
関連する問題