다중 스레드 실행에서 예외를 생성하는 C 라이브러리에 전역 정적 변수가 있습니다. 나는 그들을 어떤 식 으로든 안전하게 만들어야합니다 (즉, 각 스레드는 이러한 변수의 다른 인스턴스와 관련되어야합니다). 권장되는 방법은 무엇입니까?전역 정적 변수를 다중 스레드로 안전하게 만들기
답변
모든 C 구현에서 작동하지만 구현 관련 솔루션이있는 표준 방법은 없습니다. 예를 들어, 마이크로 소프트의 컴파일러
__declspec(thread) int tls_i = 1;
(각 스레드는이 변수의 자체 별도의 인스턴스가) 스레드 로컬 저장소에
tls_i
라이브하게, (
the docs 참조).
gcc으로, 구문 당신은 또한 주제에
wikipedia entry을 확인 할 수 있습니다
__thread int tls_i;
입니다.
대부분의 컴파일러에는 스레드 로컬 저장소를 지정하는 몇 가지 방법이 있습니다. 사용할 수 있다고 가정하면 원하는 것입니다.
첫 번째 질문 :
- 는 스레드가 변수의 자신의 사본을해야합니까?
- 또는 단일 공유 사본에 대한 액세스를 조정해야합니까?
전자가 필요하면 다른 답변은 '스레드 로컬 저장소'에 대한 제안을했습니다.
당신이 후자를 필요로한다면 어떻게 든 그 변수에 적절한 뮤텍스가 있는지 확인해야합니다 (뮤텍스의 범위는 직면 한 문제 중 하나입니다). 스레드는 모두 뮤텍스를 사용합니다. 뮤텍스를 릴리스하십시오. 이것은 더 까다 롭습니다. 변수에 대한 액세스를 제어하는 함수를 제공해야 할 수도 있습니다.
가변 errno
좌변이 수정 될 수있는 표준 인, (-DREENTRANT 컴파일) 나사 적용함에
extern int *_errno_func(void);
#define errno (*(_errno_func)())
,이 일어나는 것이다; 어쨌든 MacOS X에서는 _errno_func
대신에 __error
이라는 이름을 사용합니다 (둘 다 구현의 네임 스페이스에 있음).
변수에 대해 유사한 작업을 수행하거나해야 할 수도 있습니다. 당신이 그들이 정적이라고 말하는 사실은 약간 향상됩니다. 처리 할 파일이 하나뿐입니다 (변수를 전달할만큼 부주의하거나 포인터에 대해 충분히 부주의하지 않는 한).
는 당신이 필요로하는 것은 스레드 별 데이터 또는 스레드 개인 데이터로 알려져있다 TLS (스레드 로컬 저장소를)입니다. 이 메커니즘은 각 스레드가 다른 스레드와의 액세스를 동기화하는 것에 대해 걱정할 필요없이 자신의 개별 데이터 사본에 액세스하도록 보장 할 수 있습니다.
가 TLS 사용하는 두 가지 방법이 있습니다 :
암시 : 키워드
윈도우 사용 : __declspec (스레드) INT를 tls_var = 10; GCC와
리눅스 : __thread INT tls_var = 10
명시 :
-
하여 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
- 1. Java에서 정적 전역 변수를 사용하는 방법
- 2. CUDA 스레드로 전역 메모리 복사
- 3. 다중 스레드로 또는
- 4. 다중 스레드로 성능 향상
- 5. 다중 스레드로 작업 나누기
- 6. 정적/전역 변수
- 7. 정적 초기화 중에 스레드를 안전하게 만들 수 있습니까?
- 8. 정적 메서드의 전역 변수
- 9. 레일에서 다중 스레드로 처리해야하는 상황
- 10. CUDA에서 다중 스레드로 장치 변수 사용
- 11. C : 전역, 정적 변수 이해
- 12. Obj-C의 정적 전역 변수?
- 13. C 전역 정적 - 스레드간에 공유?
- 14. new는 윈도우에서 정적 전역 변수를 초기화 할 때 NULL을 반환합니까?
- 15. Eclipse CDT에서 정적 또는 전역 변수를 보는 방법은 무엇입니까?
- 16. C 코드베이스에서 전역 변수/정적 변수를 찾을 수있는 도구
- 17. 변수를 전역 범위에 푸시합니까?
- 18. PHP는 전역 변수를 캡슐화합니다
- 19. 전역 변수를 설정해야합니다.
- 20. C# 단일 스레드에서 다중 스레드로 전환
- 21. android에서 다중 스레드로 장벽을 만드는 방법
- 22. 파이썬에서 전역 함수 만들기
- 23. zope에 세션없이 변수를 안전하게 저장하기
- 24. 이클립스 디버거에서 전역/정적/상속 된 변수보기
- 25. 변수를 파이썬에서 스레드로 전달하는 방법은 무엇입니까?
- 26. 정적 멤버에 대한 다중 정의?
- 27. CUDA 전역 정적 데이터 대체?
- 28. UPDATE 문 수정 (더 안전하게 만들기)
- 29. 전역 변수를 사용하거나 java에서 변수를 전달해야합니까?
- 30. 이것이 전역 변수를 잘 사용할 수 있습니까?
gcc에만 해당되는 사항은 무엇입니까? – giladsah
@ giladsah : 답변의 두 번째 부분을 읽어보십시오! –
@giladsah, 확실하게, 내가 대답 한대로'__thread' 키워드 (자세한 내용은 스레드 로컬 저장소에 대한'gcc' 문서 페이지를 가리켰습니다). –