首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向量自动调整多线程代码中的危险情况吗?

向量自动调整多线程代码中的危险情况吗?
EN

Stack Overflow用户
提问于 2012-07-05 05:50:45
回答 2查看 847关注 0票数 0

可能重复: STL vector and thread-safety

一个简单的例子:

代码语言:javascript
复制
struct A {
  int a;
  void set_a (int x)
  {
    ...  // line-1
    ...  // line-2
    this->a = x;  // line-3
  }
};
...
vector<A> v;  // somewhere

假设v在线程-1和线程-2中共享。v.set_a()总是在线程-1中调用,v.push_back()在线程-2中调用.因此,不存在线程安全问题。

下面的事件序列发生了什么:

  1. 线程-1调用v.set_a()
  2. 在第3行之前,线程2调整矢量的大小(push_back()resize(),.)
  3. 当前位置没有足够的连续内存,v必须移动到其他位置

这会导致不明确的行为吗?如果是,那么对于这样的场景,最优雅的解决方案是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-05 07:26:55

标准(C++11和以前的Posix)对此非常清楚。您正在修改一个线程中的对象(向量),并从多个线程访问它,因此必须保护所有访问,包括读取访问。(至少我想。如果v.set_a()std::vector<A>类型,那么它不是合法的;我猜您指的是v[i].set_a()或类似的东西。)

这里我不确定标准的确切措辞,但我假设“修改向量”只意味着改变其大小的操作,而不是修改单个成员的操作。因此,像一个线程中的v[0] = x和另一个线程中的v[1]这样的东西,在没有同步的情况下是合法的。但是,对向量中任何对象的所有访问都是对向量的访问,因此,如果向量的大小发生变化,则必须保护对向量中对象的所有访问。这包括“延迟”访问,因为您保存了v[]返回的引用:给定如下内容:

代码语言:javascript
复制
int& ri = v[i];
//  ...
doSomethingWithRi(ri);

如果任何线程正在修改向量,则必须保护整个代码块。

票数 2
EN

Stack Overflow用户

发布于 2012-07-05 05:53:37

没有什么可以说向量大小是线程安全的,所以我们必须假设它不是,在您的例子中,我肯定会遇到问题,因为您依赖于许多非原子操作。一个优雅的解决方案就是简单地将它封装在一个线程安全版本中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11338449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档