std::map 上的哪些操作是线程安全的?

发布于 2024-08-19 22:14:01 字数 274 浏览 4 评论 0原文

假设我有:

stl::map<std::string, Foo> myMap;

以下函数线程安全吗?

myMap["xyz"] ?

即我想要一个在许多线程之间共享的巨大的只读映射;但我不知道搜索是否是线程安全的。


所有内容都首先写入一次。

然后,多个线程从中读取。

我试图避免锁定以使其尽可能快。 (我知道呀呀可能会过早优化)

Suppose I have:

stl::map<std::string, Foo> myMap;

is the following function thread safe?

myMap["xyz"] ?

I.e. I want to have this giant read-only map that is shared among many threads; but I don't know if even searching it is thread safe.


Everything is written to once first.

Then after that, multiple threads read from it.

I'm trying to avoid locks to make this as faast as possible. (yaya possible premature optimization I know)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

放血 2024-08-26 22:14:01

C++11 要求所有声明为 const 的成员函数对于多个读取器都是线程安全的。

调用 myMap["xyz"] 不是线程安全的,因为 std::map::operator[] 未声明为 const
不过,调用 myMap.at("xyz") 是线程安全的,因为 std::map::at 被声明为 const。

C++11 requires that all member functions declared as const are thread-safe for multiple readers.

Calling myMap["xyz"] is not thread-safe, as std::map::operator[] isn't declared as const.
Calling myMap.at("xyz") is thread-safe though, as std::map::at is declared as const.

孤独患者 2024-08-26 22:14:01

理论上,没有 STL 容器是线程安全的。实际上,如果容器没有被同时修改,那么读取是安全的。即该标准没有对螺纹做出规定。该标准的下一版本将和 IIUC 一起保证安全的只读行为。

如果您真的很担心,请使用带有二分搜索的排序数组。

In theory no STL containers are threadsafe. In practice reading is safe if the container is not being concurrently modified. ie the standard makes no specifications about threads. The next version of the standard will and IIUC it will then guarantee safe readonly behaviour.

If you are really concerned, use a sorted array with binary search.

夢归不見 2024-08-26 22:14:01

至少在 Microsoft 的实现中,从容器中读取是线程安全的 (参考)。

但是,std::map::operator[] 可以修改数据,并且未声明为 const。您应该使用 std::map::find(即 const)来获取 const_iterator 并取消引用它。

At least in Microsoft's implementation, reading from containers is thread-safe (reference).

However, std::map::operator[] can modify data and is not declared const. You should instead use std::map::find, which is const, to get a const_iterator and dereference it.

淡笑忘祈一世凡恋 2024-08-26 22:14:01

理论上,只读数据结构和函数不需要任何锁来保证线程安全。它本质上是线程安全的。并发内存读取没有数据竞争。但是,您必须保证仅通过单个线程进行安全初始化。

正如 Max S. 指出的那样,大多数读取映射中元素的实现(如 myMap["xyz"])不会有写入操作。如果是这样,那就安全了。但是,再次强调,您必须保证除了初始化阶段之外没有任何线程修改该结构。

Theoretically, read-only data structures and functions do not require any locks for thread-safety. It is inherently thread-safe. There are no data races on concurrent memory reads. However, you must guarantee safe initializations by only a single thread.

As Max S. pointed out, mostly implementation of reading an element in map like myMap["xyz"] would have no write operations. If so, then it is safe. But, once again, you must guarantee there is no thread which modifies the structure except the initialization phase.

氛圍 2024-08-26 22:14:01

STL 集合不是线程安全的,但向其中添加线程安全性相当简单。

最好的选择是围绕相关集合创建一个线程安全的包装器。

STL collections aren't threadsafe, but it's fairly simple to add thread safety to one.

Your best bet is create a threadsafe wrapper around the collection in question.

随心而道 2024-08-26 22:14:01

这是一个老问题,但由于所有现有答案 - 特别是已接受的答案 - 都是不正确的,我添加了另一个答案(抱歉,没有足够的代表来发表评论)。

因为OP明确提到了只读访问(_“巨型只读映射”),所以实际上不应该使用[]运算符,因为它可能会导致插入。 atfind 方法是合适的替代方法。

在线程安全的上下文中,某些非常量函数被视为 const。 atfind 就是这样的伪常量函数( 中对此进行了很好的解释)另一个问题可以从 cppreference.com 获取更多详细信息。最后,请参阅 C++11标准 23.2.2.1 为官方列表)。

只要在容器上仅使用 const 操作,执行就是线程安全的。当您在从其他线程以只读方式访问大地图之前初始化一次大地图(并且之后不要修改它)时,您是安全的!

This is an old question, but as all existing answers -and in particular the accepted one- are incorrect, I am adding another one (sorry, not enough rep for comments).

Because the OP explicitly mentions a read-only access (_"giant read-only map"), the [] operator should actually not be used since it can result in an insert. The at or find methods are suitable alternatives.

Some non-const functions are considered const in the context of thread-safety. at and find are such pseudo-const functions (this is explained very nicely in another question. More details are available from cppreference.com as well under the "thread-safety" section. And finally and see C++11 standard 23.2.2.1 for the official list).

As long as only const operations are used on the container the execution is thread-safe. As you initialize the huge map once (and do not modify it afterwards) before accessing it read-only from other threads, you are safe!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文