インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

ロックによる決定性競合

インテル® Cilk™ Plus は古い機能 (非推奨) です。代わりに、OpenMP* またはインテル® TBB を使用してください。詳細は、「インテル® Cilk™ Plus の代わりに OpenMP* またはインテル® TBB を使用するためのアプリケーションの移行」を参照してください。

ロックを適切に使用してリソース (単純な変数やリスト、その他のデータ構造など) を保護しても、実際に 2 つのストランドがリソースを変更する順序を決定することはできません。例えば、次のコードはスポーンされる関数の一部で、いくつかのストランドによって並列に実行されます。

. . .
// Update はグローバル変数 gv を変更する関数
sm.lock();
Update(gv);
sm.unlock();
. . .

この例では、複数のストランドがロック sm を取得しようとするため、gv が更新される順序は、プログラムの入力値が同じ場合でも、実行ごとに異なります。このソースは非決定的ですが、「データ競合」で定義されているデータ競合ではありません。

更新が整数加算などの可換演算の場合、この非決定性によって最終結果が異なることはないでしょう。ただし、リストの最後に要素を追加するなどの一般的な演算は可換演算ではないため、ロックが取得される順序によって結果が異なります。