2011-07-04 69 views
8

我在維護一個具有需要線程特定變量的函數的庫。 由於gcc 4.2中的一個bug,如果我在x中定義了 static __thread; 當庫函數通過來自PERL的未命名API調用時,它掛起。我想使用pthread_key_create()來定義線程局部變量,但我需要在庫中執行 ,並且在創建線程時我沒有得到任何特殊的調用。如何創建沒有__線程的pthread特定變量

如何創建一個線程局部變量,只有當它不存在? 喜歡的東西

pthread_key_t tlsKey = 0; 
int x; 

myfunc() 
{ 
    if (pthread_key_t == 0){ 
     pthread_key_create(&tlsKey, NULL); 
     pthread_setspecific(tlsKey, &x); 
    } 
    int& myx = pthread_getspecific(tlskey); 
    if (myx == 0){ 
     myx=1; 
     something_under_myx_lock(); 
     myx = 0; 
    } else { 
     cout << "locked in thread\n"; 
    } 

}

注意:如果你不知道,我之所以需要內螺紋的鎖是讓這個函數信號安全,以及線程安全的。

回答

6

要做些什麼,一旦使用pthread_once

pthread_key_t tls_key; 
pthread_once_t tls_init_flag=PTHREAD_ONCE_INIT; 

extern "C" 
{ 
    static void tls_destructor(void*); // run when thread exits to cleanup TLS data 
    static void create_tls_key() 
    { 
     if(pthread_key_create(&tls_key,tls_destructor)) 
     { 
      abort(); 
     } 
    } 
} 

pthread_key_t get_tls_key() 
{ 
    pthread_once(&tls_init_flag,create_tls_key); 
    return tls_key; 
} 

你可以調用get_tls_key()安全地從你的回調以獲取TLS關鍵,而不必擔心產生兩個鍵。

+0

爲什麼'extern「C」'? – dbbd

+0

這個問題被標記爲「C++」,所以我假定提問者正在使用C++編譯器。 'pthread_once'是一個C函數,並且期望傳遞的函數是一個指向C函數的指針。 C++和C函數不一定具有相同的調用約定/ ABI,所以'extern「C」'在技術上是必需的。在一些編譯器/平臺上可以省略。 –