2011-09-30 2 views
19

다른 스레드간에 공유되지 않는 로컬 정적 변수 (함수 호출간에 값을 유지함)를 정의하는 방법은 무엇입니까?스레드 로컬 로컬 정적 변수를 정의하는 방법은 무엇입니까?

나는 대답 C 및 C++

+0

사용중인 OS는 무엇입니까? TLS는 unixen과 windows 사이에서 이식 할 수 없습니다. – bdonlan

+3

C++ 11은 [thread_local'] (http://en.cppreference.com/w/cpp/language/storage_duration)이라는 또 다른 저장 기간을 도입했습니다. 그것을 사용해보십시오. – Nawaz

+0

OS는 windows입니다 ... –

답변

9

: TlsAlloc() /으로 TlsSetValue()/TlsGetValue()

Windows에서

고유 컴파일러 사용 (다른 POSIX 리눅스에 _declspec(thread)

를 사용을? ??) : get_thread_area() 및 관련

+0

MSDN에서 읽은 후, Tls 함수는 정확히 내가 찾고있는 함수입니다. –

+2

TlsFree를 잊어 버렸습니다 :-) –

2

현재 C 표준 스레드 또는 모두에 대한 모델이없는 모두를 찾고 있어요, 그래서 당신은 거기에 대한 답변을 얻을 수 없습니다.

POSIX에서 예측 한 유틸리티는 입니다.

다음 버전의 C 표준은 스레드를 추가하며 스레드 로컬 저장소의 개념을 갖습니다.

-3

모든 스레드에 대해 힙에서 할당 된 데이터 구조를 만들 수 있습니다.

예 : 윈도우 사용하여 Windows API에

struct ThreadLocal 
{ 
    int var1; 
    float var2; 
    //etc.. 
} 
8

함수에서 static 및 __thread를 사용하기 만하면됩니다.

예 :

int test(void) 
{ 
     static __thread a; 

     return a++; 
} 
+3

은 __thread 표준입니까? –

+2

@Ali : 아니요, GCC와 다른 컴파일러가 제공하는 확장 기능입니다. MSVC에서, 나는 당신이'__declspec (thread)'를 대신 사용한다고 생각한다. –

+3

__thread는 linux, bsd, aix 및 xl_c, gcc 및 기타 여러 컴파일러에서 작동합니다. 그것은 Windows에서 __declspec (thread)에 대해 # 정의 될 수 있습니다. –

1

당신은 스레드 ID 당 싱글로 자신의 스레드를 특정 로컬 저장소를 만들 수 있습니다. 다음과 같은 것 :

struct ThreadLocalStorage 
{ 
    ThreadLocalStorage() 
    { 
     // initialization here 
    } 
    int my_static_variable_1; 
    // more variables 
}; 

class StorageManager 
{ 
    std::map<int, ThreadLocalStorage *> m_storages; 

    ~StorageManager() 
    { // storage cleanup 
     std::map<int, ThreadLocalStorage *>::iterator it; 
     for(it = m_storages.begin(); it != m_storages.end(); ++it) 
      delete it->second; 
    } 

    ThreadLocalStorage * getStorage() 
    { 
     int thread_id = GetThreadId(); 
     if(m_storages.find(thread_id) == m_storages.end()) 
     { 
      m_storages[thread_id] = new ThreadLocalStorage; 
     } 

     return m_storages[thread_id]; 
    } 

public: 
    static ThreadLocalStorage * threadLocalStorage() 
    { 
     static StorageManager instance; 
     return instance.getStorage(); 
    } 
}; 

GetThreadId(); 호출자의 스레드 ID를 판별하기위한 플랫폼 특정 기능입니다. 이런 식으로 뭔가 : 당신은 C에 액세스 할 수 있으면 또한 C++ 11 스레드 로컬 저장소 추가를 사용할 수 있습니다

void threadFunction(void*) 
{ 
    StorageManager::threadLocalStorage()->my_static_variable_1 = 5; //every thread will have 
                  // his own instance of local storage. 
} 
+0

다중 스레드에 의한 액세스로부터'm_storages'를 보호하기 위해 동기화 (예 : 읽기/쓰기 뮤텍스)가 필요합니다. 물론 –

+0

입니다. 당신이 올바른지. – GreenScape

+0

m_storages뿐만 아니라 std :: map 및 로컬 "정적 StorageManager 인스턴스;" 스레드로부터 안전하지 않습니다. 네이티브 코드 구현시 고효율 싱글 톤은 쉬운 작업이 아닙니다. Scott Meyers 및 Andrei Alexandrescu의 "C++ 및 이중 확인 잠금의 위험성"을 참조하십시오. http://erdani.com/publications/DDJ_Jul_Aug_2004_revised.pdf – zhaorufei

2

:

int GetThreadId() 
{ 
    int id; 
#ifdef linux 
    id = (int)gettid(); 
#else // windows 
    id = (int)GetCurrentThreadId(); 
#endif 
    return id; 
} 

이제 스레드 함수 내 당신이 그것을 사용할 수는 로컬 스토리지의 ++ 11.

관련 문제