我使用 pthread TLS 实现了一种“线程本地单例”,我想知道在这种情况下如何(以及何时)删除 pthread_key_t,因为就像现在一样,TLS 密钥使用的内存永远不会释放。 d.
其预期用法是让类 A 从 ThreadLocalSingleton 派生,这使得 A 成为线程本地单例,假设 A 只有私有构造函数并且 ThreadLocalSingleton 是 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;
您的实现看起来非常优雅。
根据pthread_key_create 的开放组规范 http://pubs.opengroup.org/onlinepubs/009696799/functions/pthread_key_create.html,您不必在析构函数中将引用设置为 NULL:
可选的析构函数可以与每个键值相关联。在线程退出时,如果某个键值具有非 NULL 析构函数指针,并且线程具有与该键关联的非 NULL 值,则该键的值将设置为 NULL,然后使用先前关联的值作为其唯一参数。
我认为这也意味着关键对象本身将被 pthread 自动销毁。您只需要关心密钥后面存储的内容,这正是您的delete ((T*)obj);
does.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)