2013-04-22 2 views
5

pthread TLS를 사용하여 일종의 "스레드 로컬 싱글 톤"을 구현했으며, TLS 키에 사용 된 메모리가 절대로 사용되지 않기 때문에이 경우 pthread_key_t를 삭제할 수있는 방법을 궁금했습니다. 무료.Pthread 스레드 로컬 싱글 톤, TLS 키를 릴리스 할 때?

이의 의도 된 사용은 클래스 A는 단지 개인 생성자와을 가지고 ThreadLocalSingleton < > 가정, A A 스레드 로컬 싱글을 만드는 >는 A의 친구입니다 ThreadLocalSingleton <에서 파생 수 있도록하는 것입니다

아, 그리고 또한 - 그 구현에 어떤 문제가 보이십니까? 내가 중요한 걸 간과 했니?

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

[The Linux Programming Interface : 리눅스 및 UNIX 시스템 프로그래밍 안내서] (http://www.amazon.com/dp/1593272200)의 Kerrisk에 따르면, 당신이 * Thread Specific Data * ('pthread_key_create 'and friends) 대신 * Thread Local Storage * (정적 변수와 전역 변수의'__thread' 키워드). – jww

답변

2

구현이 매우 멋지게 보입니다.

Open Group Specification of pthread_key_create에 따르면, 당신은 소멸자에서 NULL에 대한 참조를 설정할 필요가 없습니다 :

옵션 소멸자 함수는 각 키 값과 관련 될 수있다. 스레드 종료시 키 값에 NULL이 아닌 소멸자 포인터가 있고 스레드가 해당 키와 관련된 NULL이 아닌 값을 갖는 경우 키 값이 NULL로 설정된 다음 가리키는 함수가 이전에 연관된 값을 유일한 인수로 사용합니다.

이것은 키 객체 자체가 pthread에 의해 자동으로 소멸된다는 것을 의미한다고 생각합니다. 키 바로 뒤에 저장된 내용을 처리하면됩니다. 정확히 delete ((T*)obj);의 기능입니다.