[ThreadStatic]
속성 은 어떻게 작동합니까? 컴파일러는 TLS의 값을 채우거나 검색하기 위해 일부 IL을 방출한다고 가정했지만 분해를 보면 해당 수준에서 수행하지 않는 것 같습니다.
후속 조치로서, 정적이 아닌 멤버에 배치하면 어떻게됩니까? 우리는 개발자가 실수를 저지르고 컴파일러는 경고를하지도 않습니다.
최신 정보
두 번째 질문에 대한 답변 : 정적 C #으로 수정 된 ThreadStatic
[ThreadStatic]
속성 은 어떻게 작동합니까? 컴파일러는 TLS의 값을 채우거나 검색하기 위해 일부 IL을 방출한다고 가정했지만 분해를 보면 해당 수준에서 수행하지 않는 것 같습니다.
후속 조치로서, 정적이 아닌 멤버에 배치하면 어떻게됩니까? 우리는 개발자가 실수를 저지르고 컴파일러는 경고를하지도 않습니다.
최신 정보
두 번째 질문에 대한 답변 : 정적 C #으로 수정 된 ThreadStatic
답변:
.NET jit 컴파일러에서 스레드 정적의 구현 의미는 IL 레벨 아래입니다. VB.NET 및 C #과 같이 IL로 방출하는 컴파일러는 ThreadStatic 특성을 가진 변수를 읽고 쓸 수있는 IL 코드를 방출하기 위해 Win32 TLS에 대해 아무것도 알 필요가 없습니다. C #이 아는 한 변수에는 특별한 것이 없습니다. 물건을 읽고 쓰는 위치 일뿐입니다. 그것이 속성이 있다는 사실은 C #에 아무런 영향을 미치지 않습니다. C #은 해당 심볼 이름에 대한 IL 읽기 또는 쓰기 명령어를 내기 만하면됩니다.
'무거운 리프팅'은 특정 하드웨어 아키텍처에서 IL이 작동하도록하는 핵심 CLR에 의해 수행됩니다.
그것은 왜 부적절한 (정적이 아닌) 심볼에 속성을 넣는 것이 컴파일러로부터 반응을 얻지 못하는지를 설명합니다. 컴파일러는 속성에 필요한 특수 의미를 모릅니다. 그러나 FX / Cop과 같은 코드 분석 도구는 이에 대해 알고 있어야합니다.
또 다른 방법 : CIL은 정적 (글로벌) 스토리지, 멤버 스토리지 및 스택 스토리지와 같은 스토리지 범위 세트를 정의합니다. TLS는 해당 목록에 없습니다. TLS가 해당 목록에있을 필요가 없기 때문일 가능성이 큽니다. 심볼에 TLS 속성이 태그되어있을 때 IL 읽기 및 쓰기 명령어가 TLS에 액세스하기에 충분하다면 왜 IL에 TLS에 대한 특별한 표현이나 처리가 있어야합니까? 필요하지 않습니다.
[ThreadStatic] 속성은 어떻게 작동합니까?
ThreadStatic 으로 표시된 필드 가 스레드에 연결되어 있고 수명이 스레드 수명과 비슷 하다고 생각할 수 있습니다 .
따라서 의사 코드에서 ThreadStatic
의미 론적으로 키 값이 스레드에 첨부 된 것과 유사합니다.
Thread.Current["MyClass.myVariable"] = 1;
Thread.Current["MyClass.myvariable"] += 1;
그러나 구문은 조금 더 쉽습니다.
class MyClass {
[ThreadStatic]
static int myVariable;
}
// .. then
MyClass.myVariable = 1;
MyClass.myVariable += 1;
비 정적 구성원에 배치하면 어떻게됩니까?
나는 그것이 무시된다고 믿는다.
class A {
[ThreadStatic]
public int a;
}
[Test]
public void Try() {
var a1 = new A();
var a2 = new A();
a1.a = 5;
a2.a = 10;
a1.a.Should().Be.EqualTo(5);
a2.a.Should().Be.EqualTo(10);
}
또한 ThreadStatic
상태가 공유되지 않기 때문에 일반 정적 필드와 비교할 때 동기화 메커니즘이 필요하지 않습니다.
"MyClass.myVariable"
는 그렇지 않아야합니까?
TransactionScope
범위에 대한 모든 종류의 내용을 저장합니다 ( referencesource.microsoft.com/#System.Transactions/System/… )
[ThreadStatic]은 각 스레드에서 동일한 변수의 분리 된 버전을 만듭니다.
예:
[ThreadStatic] public static int i; // Declaration of the variable i with ThreadStatic Attribute.
public static void Main()
{
new Thread(() =>
{
for (int x = 0; x < 10; x++)
{
i++;
Console.WriteLine("Thread A: {0}", i); // Uses one instance of the i variable.
}
}).Start();
new Thread(() =>
{
for (int x = 0; x < 10; x++)
{
i++;
Console.WriteLine("Thread B: {0}", i); // Uses another instance of the i variable.
}
}).Start();
}
표시된 필드는 [ThreadStatic]
스레드 로컬 스토리지에 작성되므로 모든 스레드에는 필드 사본이 있습니다. 즉 필드 범위는 스레드에 로컬입니다.
TLS 필드는 gs / fs 세그먼트 레지스터를 통해 액세스합니다. 이러한 세그먼트는 OS 커널에서 스레드 특정 메모리에 액세스하는 데 사용됩니다. OS 커널에 의해 수행됩니다.