Programing

C ++ 11 thread_local 변수는 자동으로 정적입니까?

lottogame 2020. 11. 2. 07:37
반응형

C ++ 11 thread_local 변수는 자동으로 정적입니까?


이 두 코드 세그먼트 사이에 차이점이 있습니까?

void f() {
    thread_local vector<int> V;
    V.clear();
    ... // use V as a temporary variable
}

void f() {
    static thread_local vector<int> V;
    V.clear();
    ... // use V as a temporary variable
}

배경 : 원래 STATIC 벡터 V (중간 값을 유지하기 위해 함수에 들어갈 때마다 지워짐)와 단일 스레드 프로그램이 있습니다. 프로그램을 멀티 스레딩 프로그램으로 바꾸고 싶기 때문에 어떻게 든이 정적 수정자를 제거해야합니다. 내 생각은 모든 정적을 thread_local로 바꾸고 다른 것에 대해 걱정하지 않는 것입니까? 이 접근법이 역효과를 낼 수 있습니까?


C ++ 표준에 따름

thread_local이 블록 범위의 변수에 적용될 때 명시 적으로 나타나지 않으면 스토리지 클래스 지정자 static 이 내포 됩니다.

따라서이 정의는

void f() {
    thread_local vector<int> V;
    V.clear();
    ... // use V as a temporary variable
}

다음과 같다

void f() {
    static thread_local vector<int> V;
    V.clear();
    ... // use V as a temporary variable
}

그러나 정적 변수는 thread_local 변수와 동일 하지 않습니다 .

1 thread_local 키워드로 선언 된 모든 변수에는 스레드 저장 기간이 있습니다. 이러한 엔터티에 대한 스토리지는 해당 엔터티가 생성 된 스레드 기간 동안 지속됩니다. 스레드마다 고유 한 개체 또는 참조가 있으며 선언 된 이름의 사용은 현재 스레드와 관련된 엔터티를 참조합니다.

이러한 변수를 구별하기 위해 표준은 정적 저장 기간과 함께 새로운 용어 스레드 저장 기간도입합니다 .


예, "스레드-로컬 저장소"는 "전역"(또는 "정적 저장소")과 매우 유사하지만 "전체 프로그램 기간"대신 "전체 스레드 기간"이 있다는 점만 있습니다. 따라서 블록 로컬 스레드 로컬 변수는 컨트롤이 선언을 처음 통과 할 때 초기화되지만 각 스레드 내에서 개별적으로 스레드가 종료되면 소멸됩니다.


함께 사용될 때 thread_local, static(블라드의 답변 @ 참조) 블록 범위 암시하는 반원 requied; 이름 공간 범위에 대한 연결을 의미합니다.

9.2 / 6 기준 :

클래스 정의 내에서 멤버는 static으로 선언되지 않는 한 thread_local 스토리지 클래스 지정자로 선언되지 않아야합니다.

원래 질문에 답하려면 :

C ++ 11 thread_local 변수는 자동으로 정적입니까?

네임 스페이스 범위 변수를 제외하고는 선택의 여지가 없습니다.

이 두 코드 세그먼트 사이에 차이점이 있습니까?

아니.


스레드 로컬 저장소는 정적이지만 단순한 정적 저장소와는 매우 다르게 작동합니다.

변수를 static으로 선언하면 정확히 하나의 변수 인스턴스가 있습니다. 컴파일러 / 런타임 시스템은 정확한시기를 지정하지 않고 실제로 사용하기 전에 언젠가 초기화되도록 보장합니다 (여기에서는 일부 세부 정보 생략).

C ++ 11은이 초기화가 스레드로부터 안전함을 보장하지만 C ++ 11 이전에는이 ​​스레드 안전이 보장되지 않았습니다. 예를 들면

static X * pointer = new X;

둘 이상의 스레드가 동시에 정적 초기화 코드에 도달하면 X 인스턴스가 누출 될 수 있습니다.

변수 스레드 로컬을 선언 할 때 잠재적으로 변수의 많은 인스턴스가 있습니다. 스레드 ID로 색인 된 맵에있는 것으로 생각할 수 있습니다. 즉, 각 스레드는 자체 변수 복사본을 봅니다.

다시 말하지만, 변수가 초기화되면 컴파일러 / 런타임 시스템은 데이터가 사용되기 전에이 초기화가 발생하고 변수를 사용하는 각 스레드에 대해 초기화가 발생하도록 보장합니다. 컴파일러는 또한 시작이 스레드로부터 안전하다는 것을 보장합니다.

스레드 안전성 보장은 변수가 예상 한대로 작동하도록 만드는 많은 비하인드 코드가있을 수 있음을 의미합니다. 특히 컴파일러가 스레드 수를 정확히 알 수있는 방법이 없다는 점을 고려할 때 특히 그렇습니다. 프로그램에 존재하고 이들 중 몇 개가 스레드 로컬 변수에 영향을 미칠지.

참고URL : https://stackoverflow.com/questions/22794382/are-c11-thread-local-variables-automatically-static

반응형