【问题标题】:Several Threads racing to set the same data to the same value多个线程竞相将相同的数据设置为相同的值
【发布时间】:2015-02-04 08:21:45
【问题描述】:

我有一种情况,我不得不使用黑盒包装器进行多线程处理(我怀疑它位于 TBB 线程池之上)。

我有一个值只能由具有昂贵构造函数的对象获得,并且每个线程都需要一个本地实例,这没关系。 该对象将产生一个值,该值保证跨线程始终相同(所有构造函数从主循环中获取相同的 const 形成参数)。 每个线程还可以访问该参数的共享结构并保存一些结果。

线程所需的有问题的值(无符号整数形式的迭代范围)稍后在主循环中使用,所以如果可以的话,我宁愿不创建上述对象的另一个昂贵实例只是为了再次获得相同的值。

我的问题是,在具有 VC11 的 Windows 和具有 GCC 4.8.2 的 Linux 上,在 x86-64 上,正在从多个线程将相同的值写入相同的内存位置(线程具有指向的结构中的 int)良性种族?这是一场我可以让比赛发生而不用昂贵的锁来保护价值的比赛吗?从粗略的测试来看似乎确实如此,但我不完全确定该操作是否在幕后是原子的和安全的,或者是否存在可能在压力下出现的损坏。

【问题讨论】:

  • std::atomic 会是您的解决方案吗?
  • 我总是可以通过自旋锁或使用原子属性来抢占潜在问题,当然,但为了我的利益和未来,我真的很想知道是否像我一样竞速设置值指示是安全/良性的,或者有我不知道的边缘或压力情况。我知道这通常是一个依赖于平台的问题,但我只在指定的平台上工作。感谢您的关注。
  • 您说您使用的是黑盒包装器。您确定线程不交互并且可能已经具有结构的锁定机制吗?
  • 我已经测试过,在对另一个位置进行故障排除时,我实际上可以让他们对数据进行竞争(每次执行 VS 随机设置交错的东西,或者仅在我手动锁定它时才设置为最后一个线程)。文档中也没有任何关于任何锁或固有线程安全性的指示,数据作为 void 指针传递,并在本地手动重铸到线程并留给用户。

标签: c++ multithreading thread-safety gcc4.8 visual-studio-2012


【解决方案1】:

数据竞争是否“良性”实际上取决于编译器和运行时平台。编译器假定程序是无竞争的,并且由竞争条件产生的行为是未定义的。使用原子操作不会产生太多开销,建议在这种情况下使用。

可以在这里找到一些边缘案例和非常好的例子来说明可能出错的地方: https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong

在他的帖子 ThreadSanitizer 开发人员 Dmitry Vyukov 中写道:“因此,如果数据竞争涉及非原子写入,它总是会出错”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    相关资源
    最近更新 更多