0

我有一个“侦听器”线程,它查看std::vector“接收器”,将其放入一个 size 的数组中receivers.size(),并在其上执行一个MPI_Waitany,这将返回完成接收操作的元素的数组中的索引。

然后通过以下方式从接收器向量中删除完成的元素:

receivers.erase(receivers.begin() + completed_index);

但是,其他线程可以通过以下方式将元素推送到“接收者”向量中:

receivers.push_back(receiver_message);

这很危险吗?我知道如果添加的元素导致 C++ 调整向量的大小,迭代器可能会变得无效,但是由于我擦除中的迭代器发生在一个点然后被丢弃,这不是我的目的的原子操作吗?

如果需要锁,那么每次我想访问它的任何元素时都需要锁定向量吗?例如

MPI_Start(&(receivers.at(0)->request));

即使元素 0 从不改变也需要锁吗?('request' 只是元素的一个成员)

谢谢

4

2 回答 2

3

简单的规则是,如果任何线程要写入向量(大致翻译为“以任何方式修改它”),那么您需要对所有线程使用锁以实现连贯的视图。

当且仅当向量是严格只读的,你可以不用锁。

于 2013-09-29T16:12:49.453 回答
0

在内部,STL 中的向量被实现为该向量类型的连续内存块。当您修改向量时,它可能会调整内存块的大小并将现有值复制到新位置,然后再删除旧内存。多个并发访问器可能会在旧位置更改此内部存储器,因此必须锁定。最重要的是,vector 保留了当前分配大小和当前使用情况的内部计数,这些计数无论如何都不同步。您可以在不同步的情况下销毁内部簿记。

于 2013-09-29T16:30:25.643 回答