Pthread Thread-Local-Singleton,何时释放TLS密钥? [英] Pthread Thread-Local-Singleton, when to release the TLS Key?

查看:151
本文介绍了Pthread Thread-Local-Singleton,何时释放TLS密钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用pthread TLS实现了一种线程本地单例",我想知道在这种情况下如何(以及何时)删除pthread_key_t,因为到目前为止,TLS密钥使用的内存永远不会被释放.

I implemented a kind of "thread local singleton" using pthread TLS, and i wondered how (and when) i could possibly delete the pthread_key_t in this case, because as it is now, the memory used by the TLS key will never be free'd.

其预期用途是让类A从ThreadLocalSingleton< A>派生.假设A仅具有私有构造函数,而ThreadLocalSingleton< A>则使A成为线程局部单例.是A的朋友.

The intended usage of this is to let a class A derive from ThreadLocalSingleton<A> which makes A a thread local singleton, assuming that A has only private constructors and ThreadLocalSingleton<A> is a friend of A.

哦,还有-您看到该实现有任何问题吗?我有没有忽略任何重要的事情?

Oh and also - do you see any problems with that implementation; did i overlook anything important?

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

推荐答案

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

Your implementation looks very elegant.

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

According to the Open Group Specification of pthread_key_create, you don't have to set the reference to NULL in the destructor:

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

An optional destructor function may be associated with each key value. At thread exit, if a key value has a non-NULL destructor pointer, and the thread has a non-NULL value associated with that key, the value of the key is set to NULL, and then the function pointed to is called with the previously associated value as its sole argument.

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

I think this also implies that the key object itself will be autodestroyed by pthread. You only have to take care of what's stored behind the key, which is precisely what your delete ((T*)obj); does.

这篇关于Pthread Thread-Local-Singleton,何时释放TLS密钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆