线程安全矢量

Æle*_*lex 9 c++ multithreading vector c++11

首先让我说我已经阅读了关于这个主题的大部分SO和其他主题.

我理解的方式,std :: vector 在推回新项目时重新分配内存,这是我的情况,除非我保留了足够的空间(这不是我的情况).

我所拥有的是std :: shared_ptr的向量,并且该向量包含唯一对象(或者更准确地说,指向向量中的唯一对象).

通过指针处理这些对象是围绕Factory&Handler类进行的,但是可以从包装类外部访问指向对象的指针,并且可以修改成员值.任何时候都不会发生删除.

如果我正确理解先前关于std :: vector和线程安全的SO问题中提出的问题,添加(push_back)新对象可能会使先前的指针无效,因为向量内部可能会重新分配内存并复制所有内容,这当然是一场灾难为了我.

我的意图是从该向量读取,通常通过指针修改对象,并从异步运行的线程向向量添加新项.

所以,

  1. 使用原子或互斥是不够的?如果我从一个线程推回,另一个通过指针处理对象的线程可能最终有一个无效的对象?
  2. 是否有可以处理这种形式的MT问题的库?我一直在阅读的是英特尔的TBB,但由于我已经在使用C++ 11,我希望将更改保持在最低限度,即使这对我来说意味着更多的工作 - 我想在这个过程中学习,而不仅仅是复制粘贴.
  3. 除了在修改对象时锁定访问权限,我希望对向量的异步并行读取访问不会被push_backs无效.我怎样才能做到这一点?

如果它具有任何重要性,那么以上所有内容都是在linux(debian jessie)上使用gcc-4.8并启用了c ++ 11.

我愿意使用微创库.

提前谢谢了 :-)

πάν*_*ῥεῖ 7

添加(push_back)新对象可能会使先前的指针无效...

不,此操作不会使任何先前的指针无效,除非您在向量内部数据管理中引用地址(这显然不是您的方案).
如果您存储原始指针,或者存储原始指针,std::shared_ptr那么将简单地复制这些指针,而不是无效.


正如评论中所提到的,由于std::vector多种原因,a不太适合保证生产者/消费者模式的线程安全性.既不存储引用活动实例的原始指针也是!

一个队列将更好地支持这一点.至于标准,您可以使用它std::deque来为生产者/消费者提供接入点(front(),back()).

要使这些访问点的线程安全(用于推送/弹出值),您可以使用自己的类轻松地包装它们并使用互斥锁来保护共享队列引用上的插入/删除操作.
另一个(主要的,从你的问题)点是:管理包含/引用的实例的所有权和生命周期.您也可以将所有权转让给消费者,如果这适合您的使用案例(例如从中获得开销std::unique_ptr),请参阅下文......

此外,您可能有一个信号量(条件变量),以通知消费者线程,新数据可用.


"1.使用原子或互斥是不够的?如果我从一个线程推回,另一个通过指针处理对象的线程最终会有一个无效的对象?

存储到队列(共享容器)的实例的生存期(以及因此线程安全使用)需要单独管理(例如,使用类似的智能指针std::shared_ptrstd::unique_ptr存储在那里).

"2.有图书馆......"

使用现有的标准库机制IMHO可以很好地实现它.

至于第3点.看看上面写的是什么.正如我可以进一步说明的那样,听起来你要求像rw_lock互斥体这样的东西.您可以使用合适的条件变量为此提供代理.

随意要求更多澄清......