2011-07-04 7 views
8

Utrzymuję bibliotekę, która ma funkcję, która wymaga zmiennych specyficznych dla wątku. Z powodu błędu w gcc 4.2, jeśli zdefiniuję static __thread in x; , gdy funkcja biblioteczna zostanie wywołana z nienazwanego interfejsu API z PERL, zawiesza się.Jak utworzyć specyficzne zmienne pthread bez __thread

Chciałbym zdefiniować zmienne lokalne wątku za pomocą pthread_key_create(), ale muszę to zrobić w bibliotece i nie otrzymuję żadnego specjalnego wywołania, gdy wątek jest tworzony.

Jak utworzyć zmienną lokalną wątku, tylko jeśli nie istnieje? Coś

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"; 
    } 

}

Uwaga: Jeśli zastanawiasz się, powodem muszę zamek w wątku jest, aby ten sygnał funkcja bezpieczny, a także wątek bezpieczne.

Odpowiedz

6

zrobić coś raz użyć 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; 
} 

Można połączyć get_tls_key() bezpiecznie z zwrotnego aby dostać klucz TLS bez martwienia się o utworzenie dwóch kluczy.

+0

Dlaczego "extern" C "'? – dbbd

+0

Pytanie jest oznaczone jako "C++", więc zakładam, że pytający używa kompilatora C++. 'pthread_once' jest funkcją języka C i oczekuje, że funkcja zostanie przekazana jako wskaźnik do funkcji C. Funkcje C++ i C niekoniecznie mają tę samą konwencję wywoływania/ABI, więc 'extern" C "' jest technicznie konieczne. W niektórych kompilatorach/platformach można go pominąć. –