繁体   English   中英

多线程环境中的析构函数?

[英]Destructor in a multithreaded environment?

我想知道这样一个课程会发生什么:

class MyClass
{
private:
    std::vector<int> iVector;
    void Worker()
    {
        //Lots of stuff done with iVector
        //adding, removing elements, etc.
    }
}

假设我创建了一个使用iVector并修改它的线程(由其中一个类成员函数调用)。 除了这个worker之外,该类的其他成员函数都没有读取或修改这个std :: vector。

一切似乎都很好,因为工作线程是唯一使用iVector的线程。

但是当一个对象实例被销毁时会发生什么? 即使在工作线程完成后对象被销毁,也会从主线程调用iVector的析构函数。 这会导致未定义的行为吗?

谢谢!

首先,我建议在析构函数的线程上运行std::join (或等效的库)。 这将确保在向量析构函数运行之前正确完成并同步线程。 这很重要,因为向量的生命周期必须超过使用它的线程。

C ++ 11标准,可能是后来的30.3.1.5中的状态:

5:同步:由*表示的线程的完成与(1.10)相应的成功join()返回同步。 [注意:*上的操作不同步。 - 结束说明]

现在我们必须检查1.10以获取更多细节,首先本节说明:

3:根据下面的规则,特定点处的线程T可见的对象的值是对象的初始值,由T分配给对象的值,或由另一个线程分配给该对象的值。

老实说,这很难解析,它没有详细说明连接提供什么样的同步,似乎暗示它只同步线程本身而不是它已访问的数据。 因此,我会去的安全路线和运行atomic_thread_fence(memory_order_acquire)加入主线程后,和atomic_thread_fence(memory_order_release)在之前它完成应充分保证子线程语义和没有UB之前发生。

如果执行线程正在使用ivector类成员,而另一个线程使用ivector成员销毁该对象,则继续使用ivector类成员会导致未定义的行为。

即使在工作线程完成后对象被销毁,也会从主线程调用iVector的析构函数。 这会导致未定义的行为吗?

不,如您所述,这种情况并非未定义的行为。 C ++标准不要求对象被创建对象的同一执行线程销毁。 一个执行线程增长,调整向量大小,然后消失或停止使用向量,然后一个不同的执行线程破坏整个对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM