简体   繁体   English

C ++ stl unordered_map,线程安全,其中每个线程只访问它自己分配的密钥,并可以编辑该值

[英]C++ stl unordered_map, thread safety where each thread accesses only it's own assigned key and may edit that value

Here is the scenario: 这是场景:

1) using an unordered_map<int, vector<MyClass*>*> let's say I add keys 1, 2, ... 8 1)使用unordered_map<int, vector<MyClass*>*>让我说我添加键1,2,... 8
2) all keys are set with a vector at program initialization and nothing more is added or deleted 2)在程序初始化时使用向量设置所有键,并且不再添加或删除任何键
3) I have 8 threads, where thread1 accesses key[1], thread2 accesses key[2], ... thread8 accesses key[8] (ie the thread number can only access that key number and no other key) 3)我有8个线程,其中thread1访问键[1],thread2访问键[2],... thread8访问键[8](即线程号只能访问该键号而不能访问其他键)

Sometimes I re-assign the value vector* to another heap allocated collection. 有时我会将值向量*重新分配给另一个堆分配的集合。 (ie thread1 performs key[1] = new vector<MyClass*> ) (即thread1执行key[1] = new vector<MyClass*>

I believe this will be thread safe, am I correct? 我相信这将是线程安全的,我是否正确? If not, I suppose I will use concurrent_unordered_map. 如果没有,我想我会使用concurrent_unordered_map。

thanks. 谢谢。

The answer to this question can be found in [res.on.data.races]/3 : 这个问题的答案可以在[res.on.data.races]/3

A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's non- const arguments, including this. C ++标准库函数不应直接或间接修改除当前线程以外的线程可访问的对象(1.10),除非通过函数的非const参数直接或间接访问对象,包括此参数。

Furthermore, [container.requirements.dataraces]/1 states: 此外, [container.requirements.dataraces]/1表示:

For purposes of avoiding data races ( [res.on.data.races] ), implementations shall consider the following functions to be const : begin , end , rbegin , rend , front , back , data , find , lower_bound , upper_bound , equal_range , at and, except in associative or unordered associative containers, operator[] . 为避免数据[res.on.data.races][res.on.data.races] ),实现应将以下函数视为constbeginendrbeginrendfrontbackdatafindlower_boundupper_boundequal_rangeat和,除了在关联或无序的关联容器中, operator[]

Since unordered_map::operator[] is non-const, it is legal for an implementation to modify the unordered_map when a call to operator[] occurs. 由于unordered_map :: operator []是非const的,因此在调用operator[]时修改unordered_map是合法的。 You should instead use unordered_map::find , which is explicitly required to be treated as const , and hence will not modify the unordered_map : 您应该使用unordered_map :: find ,这显然需要被视为const ,因此不会修改unordered_map

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

(As a side note, your suggested design looks like a recipe for memory leaks. Why not make it be a unordered_map<int, std::unique_ptr<vector<MyClass*>>> , or unordered_map<int,vector<MyClass*>> ?) (作为旁注,你的建议设计看起来像内存泄漏的配方。为什么不使它成为unordered_map<int, std::unique_ptr<vector<MyClass*>>> ,或unordered_map<int,vector<MyClass*>> ?)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM