pthreads
pthreadsにおける競合状態
サーチ…
前書き
例:2つのスレッドT1とT2があるとします。
どのようにそれらを検出するのですか?
同じ変数/リソース/メモリ位置が複数のスレッドからアクセス可能で、少なくともスレッドの変数/リソース/メモリ位置の値が変更されている場合は、 競合状態が発生する可能性があります。スレッドがvariable / resource / memoryの場所の値を変更していて、別のスレッドが同じものを読み込もうとすると、更新された値が取得されないためです。
注 :すべてのスレッドが変数/リソース/メモリの場所を読み込んでいるだけの場合、 競合条件は発生しません。
例:プログラムは競争条件に苦しんでいる
#include <stdio.h>
#include <pthread.h>
int x= 0;
void* fun(void* in)
{
int i;
for ( i = 0; i < 10000000; i++ )
{
x++;
}
}
int main()
{
pthread_t t1, t2;
printf("Point 1 >> X is: %d\n", x);
pthread_create(&t1, NULL, fun, NULL);
pthread_create(&t2, NULL, fun, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Point 2 >> X is: %d\n", x);
return 0;
}
私の画面上の出力は:
Point 1 >> X is: 0
Point 2 >> X is: 9925047
あなたの出力は変わります。しかし、確かにそれは2千万にはならないでしょう。両方のスレッドが同じループを実行し、グローバル変数int x;を持つのでint x;
for ( i = 0; i < 10000000; i++ )
{
x++;
}
だから、 x最終値は、 Point 2 >> X is: 9925047は20,000,000でなければなりません。しかしそうではありません。
xの状態は、xが読み込まれてから書き戻されるまでの間に別のスレッドによって変更される可能性があります。
スレッドがxの値を取得したが、それをまだ格納していないとしよう。別のスレッドは同じ値のxを取り出すこともできます(スレッドがまだ変更されていないため)。そして、両方とも同じ値(x + 1)をxに戻します!
例:
スレッド1:読み込みx、値は7
スレッド1:xに1を加え、値は8になりました
スレッド2:読み込みx、値は7
スレッド1:店舗数8
スレッド2:xに1を加え、値は8になりました
スレッド2:xを8で保存
どのようにそれらを処理するのですか?
レース条件は、共有リソースまたは相互排除にアクセスするコードの前にある種のロック機構を使用することで回避できます。
以下は変更されたプログラムです:
例:競合状態の問題が解決しました
#include <stdio.h>
#include <pthread.h>
int x= 0;
//Create mutex
pthread_mutex_t test_mutex;
void* fun(void* in)
{
int i;
for ( i = 0; i < 10000000; i++ )
{
//Lock mutex before going to change variable
pthread_mutex_lock(&test_mutex);
x++;
//Unlock mutex after changing the variable
pthread_mutex_unlock(&test_mutex);
}
}
int main()
{
pthread_t t1, t2;
printf("Point 1 >> X is: %d\n", x);
//Initlize mutex
pthread_mutex_init(&test_mutex, NULL);
pthread_create(&t1, NULL, fun, NULL);
pthread_create(&t2, NULL, fun, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
//Destroy mutex after use
pthread_mutex_destroy(&test_mutex);
printf("Point 2 >> X is: %d\n", x);
return 0;
}
出力は次のとおりです。
Point 1 >> X is: 0
Point 2 >> X is: 20000000
ここで、答えは毎回20,000,000と出てきます。
注 :レースコンディションエラーのない修正プログラムは、実行に多くの時間を要します。 mutexロックとアンロックには重荷があるためです。