std::vector 或 boost::vector 线程安全吗?

发布于 2024-12-29 17:38:00 字数 250 浏览 1 评论 0原文

我有多个线程同时在 std::vector 的共享对象上调用 push_back() 。 std::vector 线程安全吗?或者我是否需要自己实现该机制以使其线程安全?
我想避免做额外的“锁定和释放”工作,因为我是库用户而不是库设计者。我希望为向量寻找现有的线程安全解决方案。 boost::vector 怎么样,它是从 boost 1.48.0 开始新引入的。它是线程安全的吗?

I have multiple threads simultaneously calling push_back() on a shared object of std::vector. Is std::vector thread safe? Or do I need to implement the mechanism myself to make it thread safe?
I want to avoid doing extra "locking and freeing" work because I'm a library user rather than a library designer. I hope to look for existing thread-safe solutions for vector. How about boost::vector, which was newly introduced from boost 1.48.0 onward. Is it thread safe?

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

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

发布评论

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

评论(3

你是暖光i 2025-01-05 17:38:01

C++ 标准为标准 C++ 库中的所有类提供了一定的线程保证。这些保证可能不是您所期望的,但对于所有标准 C++ 库类,都做出了某些线程安全保证。不过,请务必阅读所做的保证,因为标准 C++ 容器的线程保证通常与您希望的不一致。对于某些类,会做出不同的、通常更强的保证,并且下面的答案特别适用于容器。容器本质上具有以下线程安全保证:

  1. 同一容器可以有多个并发读取器
  2. ,如果有一个写入器,则不应有更多写入器和读取器

这些通常不是人们想要的线程安全保证,但是考虑到标准容器的接口,它们是非常合理的:它们旨在在没有多个访问线程的情况下有效地使用。为其方法添加任何类型的锁定都会干扰这一点。除此之外,容器的接口对于任何形式的内部锁定都没有真正的用处:通常使用多种方法,并且访问取决于先前访问的结果。例如,在检查容器不是 empty() 后,可能会访问一个元素。然而,使用内部锁定并不能保证对象在实际访问时仍然位于容器中。

为了满足上述保证的要求,您可能必须对并发访问的容器使用某种形式的外部锁定。我不了解 boost 容器,但如果它们具有与标准容器类似的接口,我会怀疑它们具有完全相同的保证。

保证和要求在 17.6.4.10 [res.on.objects] 第 1 段中给出:

如果从不同线程调用标准库函数可能会引入数据竞争,则程序的行为是未定义的。 17.6.5.9 中规定了可能发生这种情况的条件。 [ 注意:修改在线程之间共享的标准库类型的对象会带来未定义行为的风险,除非该类型的对象被显式指定为可共享而不会出现数据争用,或者用户提供锁定机制。 ——尾注]

...和 ​​17.6.5.9 [res.on.data.races]。本节主要详细介绍了 not 中更非正式的描述。

The C++ standard makes certain threading guarantees for all the classes in the standard C++ library. These guarantees may not be what you'd expect them to be but for all standard C++ library classes certain thread safety guarantees are made. Make sure you read the guarantees made, though, as the threading guarantees of standard C++ containers don't usually align with what you would want them to be. For some classes different, usually stronger, guarantees are made and the answer below specifically applies to the containers. The containers essentially have the following thread-safety guarantees:

  1. there can be multiple concurrent readers of the same container
  2. if there is one writer, there shall be no more writers and no readers

These are typically not what people would want as thread-safety guarantees but are very reasonable given the interface of the standard containers: they are intended to be used efficiently in the absence of multiple accessing threads. Adding any sort of locking for their methods would interfere with this. Beyond this, the interface of the containers isn't really useful for any form of internal locking: generally multiple methods are used and the accesses depend on the outcome of previous accesses. For example, after having checked that a container isn't empty() an element might be accessed. However, with internal locking there is no guarantee that the object is still in the container when it is actually accessed.

To meet the requirements which give the above guarantees you will probably have to use some form of external locking for concurrently accessed containers. I don't know about the boost containers but if they have an interface similar to that of the standard containers I would suspect that they have exactly the same guarantees.

The guarantees and requirements are given in 17.6.4.10 [res.on.objects] paragraph 1:

The behavior of a program is undefined if calls to standard library functions from different threads may introduce a data race. The conditions under which this may occur are specified in 17.6.5.9. [ Note: Modifying an object of a standard library type that is shared between threads risks undefined behavior unless objects of that type are explicitly specified as being sharable without data races or the user supplies a locking mechanism. —endnote]

... and 17.6.5.9 [res.on.data.races]. This section essentially details the more informal description in the not.

静若繁花 2025-01-05 17:38:01

我有多个线程同时在 std::vector 的共享对象上调用 push_back() 。 std::vector 线程安全吗?

这是不安全的。

或者我需要自己实现该机制以使其线程安全吗?

是的。

我想避免做额外的“锁定和释放”工作,因为我是库用户而不是库设计者。我希望为向量寻找现有的线程安全解决方案。

嗯,向量的接口对于并发使用来说并不是最佳的。如果客户端有权访问锁,那就没问题,但对于为每个操作抽象锁定的接口来说,不行。事实上,向量的接口在没有外部锁的情况下无法保证线程安全(假设您需要也发生变异的操作)。

boost::vector 怎么样,它是从 boost 1.48.0 开始新引入的。线程安全吗?

文档状态:

//! boost::container::vector is similar to std::vector but it's compatible
//! with shared memory and memory mapped files.

I have multiple threads simultaneously calling push_back() on a shared object of std::vector. Is std::vector thread safe?

This is unsafe.

Or do I need to implement the mechanism myself to make it thread safe?

Yes.

I want to avoid doing extra "locking and freeing" work because I'm a library user rather than a library designer. I hope to look for existing thread-safe solutions for vector.

Well, vector's interface isn't optimal for concurrent use. It is fine if the client has access to a lock, but for for the interface to abstract locking for each operation -- no. In fact, vector's interface cannot guarantee thread safety without an external lock (assuming you need operations which also mutate).

How about boost::vector, which was newly introduced from boost 1.48.0 onward. Is it thread safe?

Docs state:

//! boost::container::vector is similar to std::vector but it's compatible
//! with shared memory and memory mapped files.
蓝梦月影 2025-01-05 17:38:01

我有多个线程同时在 std::vector 的共享对象上调用 push_back() 。 ...我希望为向量寻找现有的线程安全解决方案。

看一下 Intel 的 TBB 中的 concurrent_vector。严格来说,它在内部与 std::vector 有很大不同,并且 API 不完全兼容,但仍然可能合适。您可能会在TBB 开发人员的博客中找到其设计和功能的一些详细信息。

I have multiple threads simultaneously calling push_back() on a shared object of std::vector. ... I hope to look for existing thread-safe solutions for vector.

Take a look at concurrent_vector in Intel's TBB. Strictly speaking, it's quite different from std::vector internally and is not fully compatible by API, but still might be suitable. You might find some details of its design and functionality in the blogs of TBB developers.

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