is it necessary to call pthread_mutex_destroy on a mutex?

半城伤御伤魂 提交于 2020-01-12 07:01:08

问题


I am using pthread_mutex_t in a C++ program, as follows:

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;
};

(The class is not copyable - http://www.boost.org/doc/libs/1_53_0/boost/noncopyable.hpp)

The thing that I don't understand - is it considered an error to not call pthread_mutex_destroy in the destructor? The documentation I have read does not state that destroy must be called.

Does anyone know, what does pthread_mutex_destroy actually do and under what conditions is it required?

EDIT

Does the answer for pthread_mutex_destroy also apply to pthread_cond_destroy, etc? They seem almost like useless functions to me, unless pthread_mutex_init et. al. are allocating memory? (the docs, to me, aren't entirely clear on this.)

It doesn't hurt me to call destroy anyway, so the question is largely academic.

On linux anyway, it seems destroy only sets the mutex to an invalid state:

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;
}

(From glibc-2.14/nptl/pthread_mutex_destroy.c).


回答1:


If someone provides you with a destroy function, then you are required to call it as the final action on that object before it goes out of scope.

On architectures and implementations where the API has no effect, this will be optimised away, however if the API changes in future to require cleaning up of internal state and your code does not call it, your code will now have a memory and/or resource leak.

So the simple answer is yes; you must call this API - and here's the thing - even if the API does nothing at the moment, because although the API itself is fixed forever into the future, the implementation behind the API is not.




回答2:


From IEEE documentation which is the standard governing POSIX:

The pthread_mutex_destroy() function shall destroy the mutex object referenced by mutex; the mutex object becomes, in effect, uninitialized. An implementation may cause pthread_mutex_destroy() to set the object referenced by mutex to an invalid value. A destroyed mutex object can be reinitialized using pthread_mutex_init(); the results of otherwise referencing the object after it has been destroyed are undefined.

The documentation does not say you must call it. But it is a good practice to do so.
Calling this api will signal the POSIX library to release all the resources which were reserved for use of this particular mutex object during its initialization.
It is logical to assume mutex initialization does allocate/reserve some resources.




回答3:


A few years have gone by and @SecurityMatt was right. To settle the debate, you must call pthread_mutex_destroy to satisfy API requirements and to potentially free memory.

Here is an excerpt of the latest 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;
}


来源:https://stackoverflow.com/questions/14721229/is-it-necessary-to-call-pthread-mutex-destroy-on-a-mutex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!