为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
繁花如伊 2019-10-21 11:03:38
我有多个线程同时调用push_back()的共享对象std::vector。是std::vector线程安全的?还是我需要自己实现该机制以使其线程安全?我想避免做额外的“锁定和释放”工作,因为我是图书馆用户而不是图书馆设计师。我希望寻找现有的矢量线程安全解决方案。怎么样boost::vector,它是从Boost 1.48.0开始新引入的。它是线程安全的吗?
查看完整描述

3 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞

C ++标准为标准C ++库中的所有类提供了一定的线程保证。这些保证可能不是您期望的那样,但是对于所有标准C ++库类,都会做出某些线程安全保证。但是,请确保您已阅读保证书,因为标准C ++容器的线程保证书通常与您希望它们成为的东西不一致。对于某些不同的类(通常更强),可以做出保证,以下答案特别适用于容器。容器本质上具有以下线程安全保证:


同一容器中可以有多个并发读取器

如果只有一位作家,就不会有更多的作家,也没有读者

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


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


保证和要求在17.6.4.10 [关于对象]第1段中给出:


如果从不同线程对标准库函数的调用可能导致数据争用,则程序的行为是不确定的。17.6.5.9中指定了发生这种情况的条件。[注意:修改线程之间共享的标准库类型的对象可能会导致不确定的行为,除非该类型的对象被明确指定为可共享的,而没有数据争用或用户提供了锁定机制。--endnote]


...和17.6.5.9 [res.on.data.races]。本节从本质上详细介绍了非正式的描述。


查看完整回答
反对 回复 2019-10-21
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

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


这是不安全的。


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


是。


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


好吧,vector的接口并不是并发使用的最佳选择。如果客户端可以访问锁,但是对于接口来说,它可以抽象出每个操作的锁,那就可以了。实际上,如果没有外部锁,vector的接口就不能保证线程安全(假设您需要的操作也会发生变化)。


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


文件状态:


//! boost::container::vector is similar to std::vector but it's compatible

//! with shared memory and memory mapped files.


查看完整回答
反对 回复 2019-10-21
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

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


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


查看完整回答
反对 回复 2019-10-21
  • 3 回答
  • 0 关注
  • 2526 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信