16

次のように、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_initetでない限り、それらはほとんど役に立たない関数のように思えます。アル。メモリを割り当てていますか?(私にとって、ドキュメントはこれについて完全に明確ではありません。)

とにかくdestroyと呼んでも害はないので、質問は主に学術的なものです。

とにかくLinuxでは、destroyはmutexを無効な状態に設定するだけのようです:

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 より)。

4

3 に答える 3

18

誰かが destroy 関数を提供した場合、そのオブジェクトが範囲外になる前に、そのオブジェクトの最終アクションとしてそれを呼び出す必要があります。

API が影響を及ぼさないアーキテクチャと実装では、これは最適化されなくなりますが、API が将来変更されて内部状態のクリーンアップが必要になり、コードがそれを呼び出さない場合、コードはメモリやリソースを持つようになります。リーク。

したがって、簡単な答えはイエスです。この API を呼び出す必要があります。これが重要です。API 自体は将来的に永久に修正されますが、API の背後にある実装は修正されないため、現時点で API が何も実行しない場合でもです。

于 2013-02-06T04:00:27.113 に答える
8

POSIX を管理する標準であるIEEE ドキュメントから:

pthread_mutex_destroy() 関数は、mutex によって参照されるミューテックス オブジェクトを破棄します。つまり、mutex オブジェクトは初期化されていません。実装により、 pthread_mutex_destroy() がミューテックスによって参照されるオブジェクトを無効な値に設定する場合があります。破棄されたミューテックス オブジェクトは、pthread_mutex_init() を使用して再初期化できます。破棄された後にオブジェクトを参照した場合の結果は未定義です。

ドキュメントには、それを呼び出さなければならないとは書かれていません。しかし、そうするのは良い習慣です。
この API を呼び出すと、初期化中にこの特定のミューテックス オブジェクトの使用のために予約されたすべてのリソースを解放するように POSIX ライブラリに信号が送られます。
ミューテックスの初期化がいくつかのリソースを割り当て/予約すると仮定するのは論理的です。

于 2013-02-06T04:02:21.547 に答える
4

数年が経ち、@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;
}
于 2019-01-22T03:25:42.010 に答える