次のコードに競合状態があるのはなぜですか?
static int i=0;
void some_fun()
{
++i;
if(2==i)
{
printf("some message");
}
}
次のコードに競合状態があるのはなぜですか?
static int i=0;
void some_fun()
{
++i;
if(2==i)
{
printf("some message");
}
}
この関数が複数のスレッドから呼び出されると仮定すると、変数i
には静的ストレージ期間があり、すべてのスレッド間で共有されるため、競合状態が発生し、複数のスレッドがこの変数を変更するために競合する可能性があります。
問題は、スレッドごとに 1 つの local/auto 変数とは異なり、1 つの同じ変数が複数のスレッドで共有されることです。
競合状態を回避したい場合は、同期構造を使用してこの共有変数へのアクセスを同期する必要があります。ここで最も単純で最も関連性の高いのはミューテックスです。
これが複数のスレッドから呼び出されると仮定すると、静的変数iを保護する必要があります。これは、前述のようにロックを使用して実行できます。この場合は、より効率的なアトミックインクリメント操作を使用して実行できます。gccコンパイラを使用している場合は、次のようになります。
static int i=0;
void some_fun()
{
int local_i = __sync_add_and_fetch(&i, 1);
if(2==local_i)
{
printf("some message");
}
}
__sync_add_and_fetch()関数は、最初のパラメーターに2番目のパラメーターを追加し、合計を返します。これはすべて不可分操作として行われます。これは、ロックを取得して解放するよりも効率的です
Race condition
複数のスレッドまたはプロセスが共有リソースに同時にアクセスすると発生します。
そして、あなたのコードでは、共有リソースは i 変数です。多くの場合、私たちはそれを と呼びますcritical section
。
したがって、このコードが複数のスレッドまたはプロセスから同時にアクセスされ、変更された場合、たとえば、1 つが増加し、1 つが減少します。したがって、データは一貫性がありません。
この助けを願っています:)