9

シナリオは次のとおりです。

1)unordered_map<int, vector<MyClass*>*>たとえば、キー 1、2、... 8 を追加するとします
2) すべてのキーは、プログラムの初期化時にベクターで設定され、それ以上追加または削除されることはありません
3) スレッド 1 がキー [1] にアクセスする 8 つのスレッドがあります、スレッド 2 がキー [2] にアクセス、... スレッド 8 がキー [8] にアクセス (つまり、スレッド番号はそのキー番号にのみアクセスでき、他のキーにはアクセスできません)

値 vector* を別のヒープに割り当てられたコレクションに再割り当てすることがあります。(つまり、thread1 が実行しますkey[1] = new vector<MyClass*>)

これはスレッドセーフになると思いますが、正しいですか? そうでない場合は、concurrent_unordered_map を使用すると思います。

ありがとう。

4

1 に答える 1

11

この質問に対する答えは、次の場所にあり[res.on.data.races]/3ます。

C++ 標準ライブラリ関数は、現在のスレッド以外のスレッドによってアクセス可能なオブジェクト (1.10) を直接的または間接的に変更してはなりません (オブジェクトが関数の非 const 引数 (これを含む) を介して直接的または間接的にアクセスされない限り)。

さらに、次のように[container.requirements.dataraces]/1述べています。

データ競合 ( )を回避する目的で、実装は次の[res.on.data.races]関数を次のように見なす必要がありますconst:beginendrbeginrendfrontbackdatafindlower_boundupper_boundequal_rangeatoperator[]

unordered_map::operator[]は非 const であるため、呼び出しが発生したときに実装が変更することは合法unordered_mapですoperator[]。代わりにunordered_map::findを使用する必要があります。これは、 として扱われることが明示的に要求されているconstため、 を変更しませんunordered_map

map.find(key)->second = new vector<MyClass*>;

(ちなみに、提案された設計はメモリ リークのレシピのように見えます。それをunordered_map<int, std::unique_ptr<vector<MyClass*>>>, またはにしないのはなぜunordered_map<int,vector<MyClass*>>ですか?)

于 2012-10-30T03:29:48.230 に答える