C++11 英特尔Inspector报告共享ptr的原子存储和原子加载中的数据竞争

C++11 英特尔Inspector报告共享ptr的原子存储和原子加载中的数据竞争,c++11,stl,atomic,race-condition,intel-inspector,C++11,Stl,Atomic,Race Condition,Intel Inspector,我正在使用Visual Studio 2015预览版构建下面的代码(但我在Visual Studio 2013中遇到了类似的问题,因此它并不特定于2015),然后在Intel Inspector XE 2013 Update 9(构建328075)下运行该程序。英特尔Inspector在代码中报告了围绕访问共享的ptr及其原子内容的几个数据竞争,我只想确认事实确实如此,并了解这是Inspector中的问题还是Microsoft STL实现中的问题 这是代码,有两个线程,它们并发地和原子地修改指向

我正在使用Visual Studio 2015预览版构建下面的代码(但我在Visual Studio 2013中遇到了类似的问题,因此它并不特定于2015),然后在Intel Inspector XE 2013 Update 9(构建328075)下运行该程序。英特尔Inspector在代码中报告了围绕访问共享的ptr及其原子内容的几个数据竞争,我只想确认事实确实如此,并了解这是Inspector中的问题还是Microsoft STL实现中的问题

这是代码,有两个线程,它们并发地和原子地修改指向原子int的共享_ptr,其中一个线程还打印点(因此您可以观察控制台上打印的活动):

#包括
#包括在内,但我想在那之前找出那些误报


1.是的,代码符合要求且无数据竞争。2.遵从性实现通常可以在任何情况下忽略内存排序参数,如果它强制执行顺序一致的语义,因为
seq_cst
严格地比所有其他内存排序都强。这样做可能会影响性能,但不会影响正确性。3.我没有检查
\u Shared\u ptr\u spin\u lock
,但我强烈怀疑实现是正确的,并且Inspector报告的是假阳性。
#include <memory>
#include <atomic>
#include <thread>
#include <iostream>

using namespace std;

int main()
{
    shared_ptr<atomic<int>> a;
    atomic_store(&a, make_shared<atomic<int>>(42));

    thread t1([&]
    {
        for (int i = 0; i < 1000000; i++)
        {
            auto ptr_copy = atomic_load(&a);
            if (*ptr_copy == 42)
                *ptr_copy = 0;
        }
    });

    thread t2([&]
    {
        for (int i = 0; i < 1000000; i++)
        {
            auto ptr_copy = atomic_load(&a);
            if (*ptr_copy == 0)
            {
                atomic_store(&a, make_shared<atomic<int>>(42));
                cout << ".";
            }
        }
    });

    t1.join();
    t2.join();
}
P1: Error: Data race
  Error X22: Write: Function operator()
  Code snippet:
   28              if (*ptr_copy == 0)
   29              {
  >30                  atomic_store(&a, make_shared<atomic<int>>(42));
   31                  cout << ".";
   32              }

  Error X23: Read: Function atomic_load_explicit<struct std::atomic<int> >
  Code snippet:
   1919      {    // load *_Ptr atomically
   1920      _Shared_ptr_spin_lock _Lock;
  >1921      shared_ptr<_Ty> _Result = *_Ptr;
   1922      return (_Result);
   1923      }

  Stack (1 of 1 instance(s))
  >AtomicSharedPtrRace1.exe!atomic_load_explicit<struct std::atomic<int> > - c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory:1921
   AtomicSharedPtrRace1.exe!atomic_load<struct std::atomic<int> > - c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory:1928
   AtomicSharedPtrRace1.exe!operator() - atomicsharedptrrace1.cpp:17
template <class _Ty> inline
    shared_ptr<_Ty> atomic_load_explicit(const shared_ptr<_Ty> *_Ptr,
        memory_order)
    {   // load *_Ptr atomically
    _Shared_ptr_spin_lock _Lock;
    shared_ptr<_Ty> _Result = *_Ptr;
    return (_Result);
    }