2017-03-23 8 views
0

同じスレッドを同時に5つ追加しています。スレッド関数は次のようなものです:同じデータにアクセスするループでマルチスレッドをロック

define MAX_NUM 1000; 
int counter; 
int isMax; 

thread_function(){ 
    while (isMax == 0) { 
    if (counter < MAX_NUM) { 
     counter++ 
    } else { 
     isMax = 1; 
    } 
    } 
} 

と私はスレッドにロックを追加しようとしているので、一度に1つのスレッドだけがデータを変更します。

define MAX_NUM 1000; 
int counter; 
int isMax; 
Lock *myLock; 

thread_function(){ 
    while (isMax == 0) { 
    lock_acquire(myLock); 
    if (counter < MAX_NUM) { 
     counter++; 
    } else { 
     isMax = 1; 
    } 
    lock_release(myLock); 
    } 
} 

何らかの理由で、何らかの理由で、これによって異なるスレッドが同時にカウンタを追加するのを止めることはありません。なぜこれが動作しないのか、それを修正する方法を教えてもらえますか?

+0

私は 'lock_acquire'からの戻り値が何が間違っているのかを推測しているかもしれません。 –

+2

あなたはまた、ロックなしで複数のスレッドから 'isMax'にアクセスしています。 –

+0

あなたの 'lock_acquire'と' lock_release'関数がうまくいかないのでしょうか?完全なコードを投稿してください。 – nos

答えて

0

lock_release(myLock)の後、CPUを放棄する必要があります。 posixスレッドを使用する場合、sched_yield()を使用できます。さらに、コンパイラの中にはisMaxを最適化できるものがありますので、 "int"ではなく "volatile int"として定義してください。

0

これは、ロックを必要とせずにアトミックフェッチとアトミックという方法で解決できます。

__atomic_fetch_add(&counter, 1, __ATOMIC_SEQ_CST); 

これは、他のスレッドの動作に関係なくカウンタをインクリメントします。ただし、キャッチがあります。正確にMAX_NUMで停止したい場合、このメソッドはこの値を超える可能性があるため、エラーがあります。 ただし、カウンタは同じ値とCAS命令にを持っていることを確認するために比較交換と呼ばれる別の方法に頼ることができます。アトミックオペレーションhere

int oldCounter = counter; 
//..check here that the value < MAX_NUM 
__sync_bool_compare_and_swap(&counter, oldCounter, oldCounter+1); 

参照を。

関連する問題