繁体   English   中英

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

[英]Is std::vector or boost::vector thread safe?

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

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 中更非正式的描述。

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

这是不安全的

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

是的。

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

好吧,vector 的接口不是并发使用的最佳选择。 如果客户端可以访问锁,那很好,但是对于接口来说,为每个操作抽象锁——不。 事实上,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.

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

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

暂无
暂无

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

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