我有一个“监听器”线程,它会查看std::vector
'接收器',将其放入一个大小为receivers.size()
的数组中,并在其上执行MPI_Waitany
,这将返回完成接收操作的元素数组中的索引。
然后通过以下方式从接收器向量中删除已完成的元素:
receivers.erase(receivers.begin() + completed_index);
然而,其他线程可以通过以下方式将元素推送到“接收器”向量:
receivers.push_back(receiver_message);
这是危险的吗?我知道如果添加元素导致C ++调整向量大小,迭代器可能会变得无效,但是当我擦除中的迭代器发生在单个点然后被抛弃时,这不是我的目的的原子操作吗?
如果需要锁定,那么每次我想访问它的任何元素时,是否需要锁定向量? E.g。
MPI_Start(&(receivers.at(0)->request));
即使元素0永远不会改变,也需要锁定? ('request'只是元素的成员)
由于
答案 0 :(得分:3)
简单的规则是,如果任何线程要写入向量(它会松散地翻译为“以任何方式修改它”),那么您需要为所有线程使用锁来实现连贯的视图。 / p>
当且仅当向量是严格只读的时候,你可以不使用锁。
答案 1 :(得分:0)
在内部,STL中的向量被实现为该向量类型的连续内存块。修改向量时,可能会在删除旧内存之前调整内存块的大小并将现有值复制到新位置。多个并发访问器可能会在旧位置改变此内部存储器,因此必须锁定。除此之外,向量保持当前分配大小和当前使用的内部计数,无论如何都不会同步。您可以在不同步的情况下销毁内部簿记。