我们有一个静态(单例)类,它将在mutithreaded环境中使用。我们在其构造函数和其他mrmber函数中使用互斥锁。然而,析构函数没有互斥体。析构函数执行一些任务,例如清理其他成员对象等。 我们还需要在析构函数中使用互斥量吗?
答案 0 :(得分:3)
在访问析构函数正在破坏的对象方面,不,它不应该使用互斥锁。调用代码负责确保析构函数被调用一次,并且只调用一次;这不是析构者的责任。
在访问任何其他数据或资源方面,从析构函数访问它们没有什么特别之处。无论是从这个析构函数还是从任何普通函数调用它们,它们都将需要或不需要使用互斥锁进行保护。
答案 1 :(得分:2)
Dave为析构函数提供的rationale适用于构造函数。当对象仍在构造时,任何其他线程都不应该访问它。保证构造函数只能由一个线程运行(你不能构造两次),但你必须保证在完全构造之前没有线程访问该对象。
内部锁永远不应该是构造函数或析构函数对数据访问的责任。它们可以在析构函数中用于线程同步:如果一个对象已经在里面该对象(一个线程正在运行你的一个对象方法),以保证你不会删除中间的对象一项行动。
这是语言意义上使用的构造函数和析构函数的所有类型的通用配方。现在,对于单身人士来说,情景有点具体。通常当你谈论单例的构造函数时,你实际上是在谈论创建对象的静态方法,而不是真正的构造函数。该静态方法通常具有可包含静态互斥锁的同步机制。
在深入讨论单身人士的破坏之前,你应该说出你的预期用途。在应用程序生命周期中,单例是否会被破坏并重建多次?它会被创造一次,永远活着吗?你是如何实施单身人士的?这些问题是决定是否,何时以及何时需要同步原语的起点。
答案 2 :(得分:0)
如果您有多个尝试删除对象的线程,那么您的设计严重错误。
您必须仅在为您提供唯一实例的成员函数中使用同步,因为让多个对象请求实例是有意义的,但是您应该只有一个点决定放弃该对象而不是再使用它。
答案 3 :(得分:0)
如果析构函数修改了某些全局数据(如全局计数器等)或某些共享资源,则需要使用互斥锁。否则,保护析构函数意味着它的设计问题。任何时候线程都应该尝试在对象被其他线程使用时删除该对象。