ロックの問題

ロックの問題#

ロックは、パフォーマンスや精度の問題を引き起こす可能性があります。ロックを初めて使用する場合は、次の問題に注意してください。

デッドロック

デッドロックは、複数のスレッドが 1 つ以上のロックを取得しようとして、それぞれスレッドが異なるロックを保持しているときに発生します。デッドロックは次のような場合に発生します。

  • スレッドのサイクルがある

  • 各スレッドが少なくとも 1 つのロックをミューテックス上で保持し、すでにロックを保持しているサイクルにある次のスレッドをミューテックス上で待機している場合。

  • コアでスレッドがロックを解放しない場合。

交差点での典型的な交通渋滞を想像してみてください。それぞれの車は道路の一部を“占有”していますが、車が前へ進むためには、別の車がいる前方の道路を“占有”する必要があります。デッドロックを回避するには、次の 2 つの方法があります。

  • 同時に 2 つのロックを使用する状況を回避する。プログラムを小さなコードに分割して、1 つのロックを保持している間にそれぞれが処理を終了できるようにします。

  • 常に同じ順序でロックを取得します。例えば、“外側のコンテナー“ と “内側のコンテナー“ のミューテックスがあり、それぞれが 1 つのロックを必要とする場合は、常に “外側“ が先にロックを取得するようにします。別の例は、ロックに名前があり、“アルファベット順にロックを取得” する場合です。ロックに名前がない場合は、ミューテックスの数値アドレス順でロックを取得します。

  • ロックの代わりにアトミック操作を使用します。

コンボイ

ロックに関するもう 1 つの一般的な問題はコンボイです。コンボイは、ロックを保持しているスレッドがオペレーティング・システムにより中断されたときに発生します。その他のスレッドは、中断されたスレッドが再開し、ロックを解放するまで待機しなければなりません。公正なミューテックスでは、待機スレッドが中断されると、後続のすべてのスレッドが待機しなければならないため、状況が悪化します。

コンボイを最小限に抑えるには、ロックをできるだけ短く保持するようにしてください。ロックを取得する前に、可能な限り計算を済ませておきます。

コンボイを回避するには、可能であればロックの代わりにアトミック操作を使用します。