2016-12-14 3 views
3

私はマルチスレッドアプリケーションについて、特に競合状態を防ぐためにどのようにmutexを使用できるかについて学習しています。しかし、いくつかのコードを書いている間、私は自分のコードで競合状態(valgrindhelgrindツールを使用しています)を発見したので、ロックを解除してから復帰するまで、あるスレッドの実行が一時停止している可能性があります。mutexのロック解除と関数からの復帰の間で競合状態が発生する可能性があります

以下の例のコードを使用すると、はmutex unlockとreturn文の間で競合状態になりますか?もしそうなら、この問題をどうやって回避するのでしょうか?(バッファのある種に渡す発信者を必要と0等の一定値を返す短い)

#include <pthread.h> 

int x = 0; 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 

doSomething() 
{ 
    pthread_mutex_lock(&mutex); 
    ++x; 
    pthread_mutex_unlock(&mutex); 
       /* <-- Race Condition? */ 
    return x; 
} 

void *t2() 
{ 
    doSomething(); 
} 

main() 
{ 
    pthread_t thread; 
    pthread_t_create(&thread, NULL); 
    doSomething(); 
    pthread_join(thread, NULL); 
    return 0; 
} 

注: Iは、上記の例では、復帰「X」xと、無用であることを理解グローバルです。しかし、 'x'がライブラリ関数のためにグローバルである必要があるが、ユーザに公開することができないライブラリでは、戻り値が重要になります。

+7

ロック内のローカル変数へのxコピーし、そのコピーを代わりに返し。 – Fredrik

+2

サイドノート: 'return'は文であり、関数ではありません。式のまわりにカッコを使用しないでください。それは微妙なエラーにつながります。 – Olaf

+0

@Fredrikので、質問のパート1への答えは(ロック解除とリターンの間で可能な競合状態です)はいですか? – Ankush

答えて

7

ここでは、あなたの現在のコードでのイベントのシーケンスです:

  1. は、ロックのロックを解除します。
  2. 変数xを読んでください。
  3. あなたが読んだ値を返します。

xの読み取りは完全に保護されていません。あなたがする必要がどのような

は、共有x変数を読む

  1. です。
  2. ロックを解除します。
  3. あなたが読んだ値を返します。

このように、読み込みはロックによって保護されます。これを行うには、ロックのロックを解除する前に、非共有(ローカル)変数へxの値を格納し、戻り値として使用していること:その後、

int retval = x; 
pthread_mutex_unlock(&mutex); 
return retval; 
関連する問題