简体   繁体   English

是否允许std :: map在只读操作之后重新平衡(如Splay树)

[英]Is std::map allowed to re-balance after read-only operations (like a Splay tree)

Some binary tree data structures (such as Splay trees) will re-balance on reads to move recently accessed items toward the root, such that the subsequent look-up time may be reduced. 一些二叉树数据结构(例如Splay树)将在读取上重新平衡以将最近访问的项目移动到根,从而可以减少随后的查找时间。

Are the standard containers ( std::map , std::set ) allowed to do this? 标准容器( std::mapstd::set )是否允许这样做?

At least one concern is thread safety. 至少有一个问题是线程安全。 Previously, I'd thought that as long as you were only doing read-only operations on standard containers, it was safe to do this from multiple threads without introducing mutexes/locks etc. Maybe I need to re-think this? 以前,我认为只要你只对标准容器进行只读操作,就可以安全地从多个线程执行此操作而不引入互斥锁/锁等等。也许我需要重新考虑一下?

I know that typically red-black trees are used for the standard tree containers, and that these data structures aren't usually modified on reads. 我知道通常使用红黑树作为标准树容器,并且这些数据结构通常不会在读取时修改。 But would a hypothetical implementation that did modify be conforming? 但是,修改过的假设实现是否符合要求?

My c++-standards-foo needs improvement, but I'm not sure whether the current standard addresses thread-safety for containers. 我的c ++ - standards-foo需要改进,但我不确定当前的标准是否解决了容器的线程安全问题。 Is this different in c++0x ? 这在c++0x是不同的吗?

From the c++0x draft: c++0x草案:

§23.2.2/1: §23.2.2/ 1:

For purposes of avoiding data races (17.6.5.9), 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[]. 为避免数据争用(17.6.5.9),实现应将以下函数视为const:begin,end,rbegin,rend,front,back,data,find,lower_bound,upper_bound,equal_range,at和,除了关联或无序的关联容器,operator []。

Note that c++03 does not say anything about multi-threading, but as you say, most implementations use RB-trees, which will not rebalance on a read operation. 请注意, c++03没有提及任何有关多线程的内容,但正如您所说,大多数实现使用RB树,它不会在读取操作上重新平衡。

Read functions on maps etc. are required to have a const function defined. 地图等上的读取函数需要定义const函数。 Hence you get the guarantee that the object hasn't changed. 因此,您可以保证对象没有更改。

This is true both for C++11 ( 23.4.4.1 ) as well as C++03 ( 23.3.1 ). 对于C ++ 11(23.4.4.1)和C ++ 03(23.3.1)都是如此。

23.2.2 of the new C++11 standard may be of special interest here: 新的C ++ 11标准的23.2.2在这里可能特别感兴趣:

  1. For purposes of avoiding data races (17.6.5.9), 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[]. 为避免数据争用(17.6.5.9),实现应将以下函数视为const:begin,end,rbegin,rend,front,back,data,find,lower_bound,upper_bound,equal_range,at和,除了关联或无序的关联容器,operator []。

  2. Notwithstanding (17.6.5.9), implementations are required to avoid data races when the contents of the contained object in different elements in the same sequence, excepting vector<bool> , are modified concurrently. 尽管如此(17.6.5.9),除了vector<bool> ,同时修改同一序列中不同元素中包含对象的内容时,还需要实现以避免数据争用。

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

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