6

pthread TLS を使用して一種の「スレッド ローカル シングルトン」を実装しましたが、この場合、どのように (そしていつ) pthread_key_t を削除できるか疑問に思いました。現在のように、TLS キーによって使用されるメモリは決して解放されないからです。 d.

これの使用目的は、A がプライベート コンストラクターのみを持ち、ThreadLocalSingleton<A> が A のフレンドであると仮定して、A をスレッド ローカル シングルトンにする ThreadLocalSingleton<A> からクラス A を派生させることです。

ああ、また、その実装に問題はありますか。重要なことを見落としていませんか?

#include <pthread.h>
#include <iostream>

template <class T>
class ThreadLocalSingleton
{
private:
    static pthread_key_t tlsKey;
    static pthread_once_t tlsKey_once;

    static void tls_make_key()
    {
        (void)pthread_key_create(&ThreadLocalSingleton::tlsKey, ThreadLocalSingleton::tls_destructor);
    }

    static void tls_destructor(void* obj)
    {
        delete ((T*)obj);
        pthread_setspecific(tlsKey, NULL); // necessary or it will call the destructor again.
    }

public:

    /*
     * A thread-local singleton getter, the resulted object must never be released,
     * it is auto-released when the thread exits.
     */
    static T* getThreadInstance(void)
    {
        pthread_once(&tlsKey_once, ThreadLocalSingleton::tls_make_key);
        T* instance = (T*)pthread_getspecific(tlsKey);
        if(!instance)
        {
            try
            {
                instance = new T;
                pthread_setspecific(tlsKey, instance);
            }
            catch (const char* ex)
            {
                printf("Exception during thread local singleton init: %s\n",ex);
            }
        }
        return instance;
    }
};
template <class T>
pthread_key_t ThreadLocalSingleton<T>::tlsKey;
template <class T>
pthread_once_t ThreadLocalSingleton<T>::tlsKey_once = PTHREAD_ONCE_INIT;
4

1 に答える 1

2

あなたの実装はとてもエレガントに見えます。

pthread_key_createのオープン グループ仕様によると、デストラクタで NULL への参照を設定する必要はありません。

オプションのデストラクタ関数を各キー値に関連付けることができます。スレッドの終了時に、キー値に NULL 以外のデストラクタ ポインタがあり、スレッドがそのキーに関連付けられた NULL 以外の値を持っている場合、キーの値は NULL に設定され、ポイントされている関数が呼び出されます。唯一の引数として以前に関連付けられた値。

これは、キー オブジェクト自体が pthread によって自動破棄されることも意味していると思います。キーの背後に格納されているものだけを処理する必要があります。これは、まさにあなたdelete ((T*)obj);が行うことです。

于 2013-08-13T15:03:34.653 に答える