3

これは私がこれまでに行ったことです:

class mutexLocker
{
    private:
    /* Declaration of a Mutex variable `mutexA`. */
    pthread_mutex_t &mutexA;

    /* `mutexStatus` holds the return value of the function`pthread_mutex_lock `. 
    This value has to be returned to the callee so we need to preserve it in a class
    variable. */
    int             mutexStatus;

    /* We need to decide how to deal with the situation when one thread tries to lock then
    mutex repeatedly. If the mutex is of type recursive, then there won't be any problem for 
    sure, but otherwise the case may result in a deadlock. */
    pthread_t       calleeThreadId;

    public:
    /* Constructor attempts to lock the desired mutex variable. */
    mutexLocker (pthread_mutex_t argMutexVariable, pthread_t threadId) 
    : mutexA (argMutexVariable, calleeThreadId)
    {
        /* Return value is needed in order to know whether the mutex has been 
        successfully locked or not. */
        int mutexStatus = pthread_mutex_lock (&argMutexVariable);
    }

    /* Since the constructor can't return anything, we need to have a separate function
    which returns the status of the lock. */
    int getMutexLockStatus ()
    {
        return mutexStatus;
    }

    /* The destructor will get called automatically whereever the callee's scope ends, and
    will get the mutex unlocked. */
    ~mutexLocker ()
    {
        pthread_mutex_unlock (&mutexA);
    }
};

DIY ミューテックス ロッカー クラスには、他にどのような機能を提供する必要がありますか?

4

3 に答える 3

5

あなたはこれに少し後ろ向きに近づいています。直面している問題を解決するためのコードを記述します。持っていない問題を解決するためのコードを書かないでください。「あなたはそれを必要としないだろう」は良い原則です。

それらで解決できる問題がない限り、他の機能を提供するべきではありません。あなたが何も言及していないことを考えると、あなたはそのような問題を抱えていないと思います。したがって、他の機能はまだ追加しないでください。

于 2012-08-16T06:24:59.883 に答える
5

ユースケースがない機能を作成しないという Slavik81 のコメントに完全に同意します。

それにもかかわらず、ロック クラスの Boost 実装を参照することは、それらのインターフェイスの一般的な要件を理解するという点で良い出発点になる可能性があります。スレッド.同期.ロック

標準 C++11 の導入に関してはstd::lock_guard: http://en.cppreference.com/w/cpp/thread/lock_guard

于 2012-08-16T06:41:14.077 に答える
1

まず、Graeme と Slavik81 の回答はどちらも非常に優れています (+1)。

さて、何を追加するかについては:

  • エラーの処理方法によっては、追加のエラー サポートが必要になる場合があります。たとえば、ロックに失敗した場合にチームが例外をスローする場合、クラスは例外を作成してスローできます。
  • 診断として、取得が成功したことをテストしたクライアントを検証することをお勧めします (たとえばassert、ロックが成功したことを確認していない場合は dtor で)。
  • 「再試行」取得機能が必要な場合があります。例外をスローする前に再試行することをお勧めします。個人的には、プログラマーのエラーだと思いますEBUSY-- 長いロックを保持しないでください!
  • またpthread_mutex_t、クラスであなたを隠してください-コピー、割り当てなどを禁止してください。それをロッカーに渡します。
  • 一部のクライアントは、ステータスを評価するのではなく、成功をテストするための簡単な方法を希望する場合があります。使い方次第です。
  • ロックを取得していない場合は、dtor でロックを解除しないでください
  • ロック解除の結果を確認します。このシナリオでのエラー処理を決定します。

おそらくもっと重要なのは、何を削除するかを決定することです。

  • コピーなし。copy ctor を明示的に削除すると、意図が表れます。
  • 削除operator=-- 意図を表します。
  • 移動を削除
  • calleeThreadId: 役に立たない場合は削除してください。具体的には、提案しているこのエラー検出を実際にどのように実装するかを検討してください。ロッカーはデータの場所が間違っているようです。私はこれらのロッカーを最小限に抑え、集中し、シンプルにすることを好みます。
  • 余分なマイル: ヒープ割り当てを防ぎます。たとえば、演算子 new/delete のプライマリ バリアントを削除します。
  • 再試行しない場合、ステータスは になる可能性がありますconst
  • 保持する場合は、threadID もconst.

最後に、参照によってミューテックスを渡します(ただし、タイプミスだと思います)。

于 2012-08-16T07:03:54.263 に答える