1. ホーム
  2. multithreading

[解決済み] レースコンディションとは何ですか?

2022-03-19 13:31:57

質問

マルチスレッドアプリケーションを記述する際、最もよく経験する問題の1つはレースコンディションです。

コミュニティへの質問です。

  • レースコンディションとは何ですか?
  • どのように検出するのですか?
  • どのように対処するのですか?
  • 最後に、その発生を防ぐにはどうしたらよいのでしょうか。

どのように解決するのか?

レースコンディションは、2つ以上のスレッドが共有データにアクセスでき、それらが同時にデータを変更しようとしたときに発生します。スレッドスケジューリングアルゴリズムはいつでもスレッド間を入れ替えることができるため、スレッドが共有データにアクセスしようとする順序はわかりません。したがって、データの変更の結果はスレッドスケジューリングアルゴリズムに依存し、すなわち両方のスレッドがデータにアクセス/変更するために "race"していることになります。

あるスレッドが "check-then-act" (例えば "check" 値が X であれば "act" 値が X であることに依存する何かを行う) を行い、別のスレッドが "check" と "act" の間に値に何かを行った場合に問題がよく発生します。例えば

if (x == 5) // The "Check"
{
   y = x * 2; // The "Act"

   // If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
   // y will not be equal to 10.
}

要は、チェックと行為の間に他のスレッドがxを変更したかどうかによって、yは10にもなり得るし、何にもなり得るということです。あなたにはそれを知る本当の方法はないのです。

レースコンディションの発生を防ぐために、通常、共有データにロックをかけ、一度に1つのスレッドしかデータにアクセスできないようにします。これは、次のようなことを意味します。

// Obtain lock for x
if (x == 5)
{
   y = x * 2; // Now, nothing can change x until the lock is released. 
              // Therefore y = 10
}
// release lock for x