是否访问std :: unique_ptr类型的指针应用内存排序?

问题描述 投票:0回答:1

假设我们有一个类型为Wrapper的全局对象,该对象具有不是nullptr的std::unique_ptr<MyObject> m_pUnique成员。然后在线程1中将m_pUnique设置为nullptr,因此将调用MyObject的析构函数,然后该线程退出。线程1退出后,线程2调用Wrapper对象的析构函数。问题是:

  1. 线程1退出后,线程2是否会看到m_pUnique为nullptr?(我听说线程退出时会发生一些内存排序(这种情况是线程1),但不确定读取m_pUnique指针值(而不读取其内部对象值)的线程2是否会看到新的指针值。) >
  2. 如果线程2没有看到m_pUnique现在为nullptr,是否有可能再次调用m_pUniqueMyObject的析构函数?
  3. 简化代码示例:

    class Wrapper
    {
    public:
      std::unique_ptr<MyObject> m_pUnique;
    }    

    //Global var created somewhere e.g. in thread 0
    Wrapper* someWrapper = new Wrapper();     
    someWrapper.reset(new MyObject);
    //...

    //sets m_pUnique to nullptr, which calls MyObject's destructor and then threads exits
    Thread1Func() 
    {
      someWrapper.m_pUnique = nullptr; 
    }  

    //delete Wrapper object after thread 1 has exited  
    Thread2Func()
    {
      delete someWrapper;
    }

假设我们有一个Wrapper类型的全局对象,它的std :: unique_ptr m_pUnique成员,它不是nullptr。然后在线程1中将m_pUnique设置为nullptr,因此...

c++ multithreading memory-barriers
1个回答
0
投票

如果线程2已经从someWrapper读取m_pUnique,那么除非保证该成员被标记为volatile或原子化,否则不能保证(不暗示障碍)它将发现m_pUnique已更改。

但是,在调用析构函数时,将运行必须重新检查对象的不同代码,因此,假设您的CPU支持缓存和核心一致性,则析构函数将看到m_pUnique已经为nullptr。这样可以防止目标对象被双重破坏。

© www.soinside.com 2019 - 2024. All rights reserved.