我正在研究一个在下面使用std::map
的多线程应用程序。我知道向std::map
写入不是线程安全的,并且在写入时需要锁定树。
但是,我找不到“写作”的定义。它是否仅包括用于从树中插入或删除元素的操作?还是在树中修改元素的值也算作写入?
?考虑std::map<int, MyClass> Test
,其中MyClass
具有成员变量int x
。
比方说MyClass& t = Test.at(7);
。然后t.x++
被认为是对地图的写了吗?
答案 0 :(得分:2)
然后t.x ++被认为是对地图的写信吗?
是的。您正在更新地图中项目的值。那是在写地图。
这类似于更新数组中元素的值。
int array[5] = {};
int& item = array[2];
++item; // This is writing to the array.
就您而言,
MyClass& t = Test.at(7);
返回对地图中某个项目的引用。如果t
的值被更新,则地图也将被更新。
获得该问题答案的另一个线索是const
对象的std::map::at()
的返回值。
T& at( const Key& key );
const T& at( const Key& key ) const;
如您所见,该库不允许您将std::map::at()
对象的调用返回对象修改为const
。即该库将对函数返回值的任何修改都视为对std::map
对象的修改。
答案 1 :(得分:2)
什么算作“写入” std :: map?
取决于上下文。
还是在树中修改元素的值也算作写操作?
它算作对该元素的写操作。
它不算作对树†结构的修改。因此,修改一个map元素并同时读取其他元素或遍历map是线程安全的,而在并发插入或擦除元素而没有同步的情况下这样做确实是不安全的。
是否需要同步以同时读取和修改同一元素取决于元素对象是否是线程安全的。
† Standard并未明确要求或保证std::map
是一棵树。但它总是使用树来实现。