是否有必要在互斥锁上调用pthread_mutex_destroy?

时间:2013-02-06 03:55:53

标签: c++ pthreads posix mutex

我在C ++程序中使用pthread_mutex_t,如下所示:

class Mutex : public noncopyable
{
public:
    Mutex()
    {
        pthread_mutex_init(&m_mutex, NULL);
    }

    void acquire()
    {
        pthread_mutex_lock(&m_mutex);
    }

    void release()
    {
        pthread_mutex_unlock(&m_mutex);
    }

private:
    pthread_mutex_t m_mutex;
};

(该课程不可复制 - http://www.boost.org/doc/libs/1_53_0/boost/noncopyable.hpp

我不理解的事情 - 在析构函数中调用pthread_mutex_destroy被认为是错误的?我读过的文档没有声明必须调用destroy。

有谁知道,pthread_mutex_destroy实际做了什么以及在什么条件下需要它?

修改

pthread_mutex_destroy的答案是否也适用于pthread_cond_destroy等?除非pthread_mutex_init等,否则它们对我来说几乎就像是无用的功能。人。分配内存? (对我来说,文档对此并不完全清楚。)

无论如何都要打电话给我,这个问题主要是学术性的。

无论如何,在linux上,似乎只会将互斥锁设置为无效状态:

int
__pthread_mutex_destroy (mutex)
     pthread_mutex_t *mutex;
{
  if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
      && mutex->__data.__nusers != 0)
    return EBUSY;

  /* Set to an invalid value.  */
  mutex->__data.__kind = -1;

  return 0;
}

(来自glibc-2.14 / nptl / pthread_mutex_destroy.c)。

3 个答案:

答案 0 :(得分:13)

如果某人为您提供了销毁功能,那么您需要在该对象超出范围之前将其作为该对象的最终操作。

在API无效的架构和实现上,这将被优化掉,但是如果API在将来发生变化以要求清理内部状态并且您的代码没有调用它,那么您的代码现在将具有内存和/或资源泄漏。

所以简单的答案是肯定的;你必须调用这个API - 这就是事情 - ,即使API目前什么都不做,因为虽然API本身将永远固定在未来,但API背后的实现却不是。

答案 1 :(得分:5)

来自 IEEE documentation ,这是管理POSIX的标准:

  

pthread_mutex_destroy()函数将销毁互斥锁​​引用的互斥锁对象;实际上,互斥对象变得未初始化。实现可能会导致pthread_mutex_destroy()将互斥引用的对象设置为无效值。可以使用pthread_mutex_init()重新初始化已销毁的互斥锁对象;

之后,在销毁对象之后引用对象的结果是不确定的。

文档未说明必须调用它。但这样做是一种很好的做法 调用此api将通知POSIX库释放在初始化期间保留用于此特定互斥对象的所有资源。
假设互斥初始化确实分配/保留了一些资源是合乎逻辑的。

答案 2 :(得分:1)

几年过去了,@ SecurityMatt是正确的。要解决辩论,必须调用pthread_mutex_destroy以满足API要求并可能释放内存。

以下是最新pthread_mutex_destroy的摘录:

int _pthread_mutex_destroy (pthread_mutex_t *mutex)
{
  if (mutex->__attr == __PTHREAD_ERRORCHECK_MUTEXATTR
      || mutex->__attr == __PTHREAD_RECURSIVE_MUTEXATTR)
    /* Static attributes.  */
    ;
  else
    free (mutex->__attr);

  return 0;
}