Pthread Thread-Local-Singleton,何时释放TLS密钥?

Pon*_*don 6 singleton pthreads thread-local-storage

我使用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;
Run Code Online (Sandbox Code Playgroud)

oni*_*ake 2

您的实现看起来非常优雅。

根据pthread_key_create 的开放组规范,您不必在析构函数中将引用设置为 NULL:

可选的析构函数可以与每个键值相关联。在线程退出时,如果某个键值具有非 NULL 析构函数指针,并且该线程具有与该键关联的非 NULL 值,则该键的值将设置为 NULL,然后使用先前关联的值作为其唯一参数。

我认为这也意味着关键对象本身将被 pthread 自动销毁。您只需要关心密钥后面存储的内容,这正是您delete ((T*)obj);所做的。