2010-04-18 3 views
4

다중 스레드 실행에서 예외를 생성하는 C 라이브러리에 전역 정적 변수가 있습니다. 나는 그들을 어떤 식 으로든 안전하게 만들어야합니다 (즉, 각 스레드는 이러한 변수의 다른 인스턴스와 관련되어야합니다). 권장되는 방법은 무엇입니까?전역 정적 변수를 다중 스레드로 안전하게 만들기

답변

9

모든 C 구현에서 작동하지만 구현 관련 솔루션이있는 표준 방법은 없습니다. 예를 들어, 마이크로 소프트의 컴파일러

__declspec(thread) int tls_i = 1; 

(각 스레드는이 변수의 자체 별도의 인스턴스가) 스레드 로컬 저장소에 tls_i 라이브하게, ( the docs 참조). gcc으로, 구문 당신은 또한 주제에 wikipedia entry을 확인 할 수 있습니다

__thread int tls_i; 

입니다.

+0

gcc에만 해당되는 사항은 무엇입니까? – giladsah

+0

@ giladsah : 답변의 두 번째 부분을 읽어보십시오! –

+0

@giladsah, 확실하게, 내가 대답 한대로'__thread' 키워드 (자세한 내용은 스레드 로컬 저장소에 대한'gcc' 문서 페이지를 가리켰습니다). –

1

대부분의 컴파일러에는 스레드 로컬 저장소를 지정하는 몇 가지 방법이 있습니다. 사용할 수 있다고 가정하면 원하는 것입니다.

4

첫 번째 질문 :

  • 는 스레드가 변수의 자신의 사본을해야합니까?
  • 또는 단일 공유 사본에 대한 액세스를 조정해야합니까?

전자가 필요하면 다른 답변은 '스레드 로컬 저장소'에 대한 제안을했습니다.

당신이 후자를 필요로한다면 어떻게 든 그 변수에 적절한 뮤텍스가 있는지 확인해야합니다 (뮤텍스의 범위는 직면 한 문제 중 하나입니다). 스레드는 모두 뮤텍스를 사용합니다. 뮤텍스를 릴리스하십시오. 이것은 더 까다 롭습니다. 변수에 대한 액세스를 제어하는 ​​함수를 제공해야 할 수도 있습니다.

가변 errno 좌변이 수정 될 수있는 표준 인, (-DREENTRANT 컴파일) 나사 적용함에

extern int *_errno_func(void); 
#define errno (*(_errno_func)()) 

,이 일어나는 것이다; 어쨌든 MacOS X에서는 _errno_func 대신에 __error이라는 이름을 사용합니다 (둘 다 구현의 네임 스페이스에 있음).

변수에 대해 유사한 작업을 수행하거나해야 할 수도 있습니다. 당신이 그들이 정적이라고 말하는 사실은 약간 향상됩니다. 처리 할 파일이 하나뿐입니다 (변수를 전달할만큼 부주의하거나 포인터에 대해 충분히 부주의하지 않는 한).

3

는 당신이 필요로하는 것은 스레드 별 데이터 또는 스레드 개인 데이터로 알려져있다 TLS (스레드 로컬 저장소를)입니다. 이 메커니즘은 각 스레드가 다른 스레드와의 액세스를 동기화하는 것에 대해 걱정할 필요없이 자신의 개별 데이터 사본에 액세스하도록 보장 할 수 있습니다.


가 TLS 사용하는 두 가지 방법이 있습니다 :

  1. 암시 : 키워드

    윈도우 사용 : __declspec (스레드) INT를 tls_var = 10; GCC와

    리눅스 : __thread INT tls_var = 10

  2. 명시 :

      하여 TlsAlloc() : API 관련

      윈도우 특정 TLS를 사용하여은 TLS 데이터를위한 메모리를 할당

      TlsFree() : 무료 메모리 tls 데이터
      으로 TlsSetValue() : 설정 TLS 가치
      TlsGetValue() : TLS받을 가치

    자세한 내용은 MSDN을 참조하십시오.

    GCC와

    리눅스 :

      pthread_key_create는() :) (을 TLS 데이터
      pthread_key_delete를 작성 (TLS를 데이터
      pthread_getspecific는을 32 파괴) : TLS 가치
      pthread_setspecific는 얻을() : set tls 'value
    구체적이고 자세한 정보는 맨 페이지를 참조하십시오.

관련 문제