2 つのスレッドからアクセスされる STL マップがあります。どちらも要素を挿入も削除もせず、単に読み取ります。
単純な配列であれば、これで問題が発生することはないと確信しています。ただし、STL マップは複雑なデータ構造であり、その実装は私にはわかりません。これによりデータ競合が発生しますか?
2 つのスレッドからアクセスされる STL マップがあります。どちらも要素を挿入も削除もせず、単に読み取ります。
単純な配列であれば、これで問題が発生することはないと確信しています。ただし、STL マップは複雑なデータ構造であり、その実装は私にはわかりません。これによりデータ競合が発生しますか?
標準の C++ コンテナー (2011 年現在) では、複数の同時リーダー (const
メンバー関数経由) による安全なアクセスが可能です。
つまり、問題ありません (const
コンテナーで使用している型のメンバー関数が同じ規則に従うと仮定します: ビット単位 -const
他のスレッドによるアクセスから保護されているオブジェクトを除きます)。
古い実装を使用している場合、理論的には問題があるかもしれませんが、私はそれを疑っています。
以下は、The Standard のライブラリ紹介セクションの全体の一部です ( N3337
)。これらの段落の 1 つだけでは、あなたの質問に答えるのに十分ではないと思います。
17.6.5.9 データ競合の回避[res.on.data.races]
1 このセクションでは、実装がデータ競合 (1.10) を防止するために満たさなければならない要件を指定します。特に指定のない限り、すべての標準ライブラリ関数は各要件を満たす必要があります。以下に指定されている場合以外の場合、実装によってデータ競合が防止される場合があります。
2 C++ 標準ライブラリ関数は、現在のスレッド以外のスレッドによってアクセス可能なオブジェクト (1.10) に直接または間接的にアクセスしてはなりません。
3 C++ 標準ライブラリ関数は、現在のスレッド以外のスレッドによってアクセス可能なオブジェクト (1.10) を直接的または間接的に変更してはなりません。ただし、これを含む関数の非 const 引数を介して直接的または間接的にオブジェクトにアクセスする場合を除きます。
4 [注: これは、たとえば、スレッド間でオブジェクトを明示的に共有しないプログラムでもデータ競合が発生する可能性があるため、同期なしで実装が内部目的で静的オブジェクトを使用できないことを意味します。—終わりのメモ]
5 C++ 標準ライブラリ関数は、その引数またはそのコンテナー引数の要素を介して間接的にアクセス可能なオブジェクトにアクセスしてはなりません。
6 標準ライブラリ コンテナーまたは文字列メンバー関数を呼び出すことによって取得された反復子に対する操作は、基になるコンテナーにアクセスできますが、それを変更してはなりません。[ 注: 特に、イテレーターを無効にするコンテナー操作は、そのコンテナーに関連付けられたイテレーターの操作と競合します。—終わりのメモ]
7 オブジェクトがユーザーに表示されず、データ競合から保護されている場合、実装はスレッド間で独自の内部オブジェクトを共有できます。
8 別段の指定がない限り、C++ 標準ライブラリ関数は、それらの操作がユーザーに見える効果 (1.10) を持つ場合、現在のスレッド内でのみすべての操作を実行するものとします。
9 [ 注: これにより、目に見える副作用がなければ、実装で操作を並列化できます。—終わりのメモ]