我有一个将由两个线程访问的 STL 映射。它们既不插入也不删除元素:它们只是读取。
如果它只是一个简单的数组,我相信这永远不会造成麻烦。但是,STL 映射是一个复杂的数据结构,我不知道它的实现。这会导致数据竞争吗?
我有一个将由两个线程访问的 STL 映射。它们既不插入也不删除元素:它们只是读取。
如果它只是一个简单的数组,我相信这永远不会造成麻烦。但是,STL 映射是一个复杂的数据结构,我不知道它的实现。这会导致数据竞争吗?
标准 C++ 容器(截至 2011 年)允许多个并发读取器安全访问(即通过const
成员函数)。
也就是说,您没问题(假设const
您与容器一起使用的类型上的成员函数遵循相同的规则:按位 -const
除了受保护免受其他线程访问的对象)。
如果您使用的是旧实现,理论上您可能会遇到问题,但我对此表示怀疑。
N3337
这是标准 ( )的库介绍部分的全部内容。我认为这些段落中的任何一段都不足以回答你的问题,所以你得到了全部!
17.6.5.9 避免数据竞争[res.on.data.races]
1 本节规定了实施应满足的要求,以防止数据竞争 (1.10)。除非另有说明,否则每个标准库函数都应满足每个要求。实施可能会在下面指定的情况以外的情况下防止数据竞争。
2 C++ 标准库函数不应直接或间接访问可由当前线程以外的线程访问的对象 (1.10),除非通过函数的参数直接或间接访问对象,包括 this。
3 C++ 标准库函数不得直接或间接修改可由当前线程以外的线程访问的对象 (1.10),除非通过函数的非 const 参数直接或间接访问对象,包括 this。
4 [注:这意味着,例如,实现不能在没有同步的情况下将静态对象用于内部目的,因为即使在没有显式在线程之间共享对象的程序中,它也可能导致数据竞争。——尾注]
5 C++ 标准库函数不应访问通过其参数或通过其容器参数的元素间接访问的对象,除非通过调用其规范要求的那些容器元素的函数。
6 通过调用标准库容器或字符串成员函数获得的迭代器上的操作可以访问底层容器,但不得修改它。[注意:特别是,使迭代器无效的容器操作与与该容器关联的迭代器上的操作相冲突。——尾注]
7 如果对象对用户不可见并且受到保护以防止数据竞争,则实现可以在线程之间共享它们自己的内部对象。
8 除非另有说明,否则 C++ 标准库函数应仅在当前线程内执行所有操作,前提是这些操作具有对用户可见 (1.10) 的效果。
9 [注意:如果没有可见的副作用,这允许实现并行化操作。——尾注]