ThreadStatic özniteliği nasıl çalışır?


138

[ThreadStatic]Özellik nasıl çalışır? Derleyicinin, TLS'deki değeri doldurmak / almak için bazı IL yayacağını varsaydım, ancak bir demontaja bakıldığında, bu düzeyde yapmıyor gibi görünüyor.

Bir takip olarak, statik olmayan bir üyeye koyarsanız ne olur? Bu hatayı yapan bir geliştiricimiz vardı ve derleyici bir uyarı bile vermiyor.

Güncelleme

İkinci soru burada cevaplandı: ThreadStatic, Statik C # ile Değiştirildi


1
Oluşturulan IL aynı ise (ki aslında), çalışma zamanının, böyle dekore edilmiş bir alana çarptığında değerin nasıl tahsis edileceğini ve okunacağını bilmek için özel olarak kodlanması gerekir. Hack gibi görünüyor :)
Rex M

Yanıtlar:


92

İş parçacığı statik uygulama semantiği, IL jit derleyicisinde IL düzeyinin altındadır. ThreadStatic özniteliğine sahip bir değişkeni okuyabilen ve yazabilen IL kodunu yaymak için VB.NET ve C # gibi IL'ye yayılan derleyicilerin Win32 TLS hakkında hiçbir şey bilmeleri gerekmez. C # 'ın bildiği kadarıyla değişken hakkında özel bir şey yok - sadece bir şeyler okumak ve yazmak için bir konum. Üzerinde bir özniteliği olması, C # için bir sonuç oluşturmaz. C #, yalnızca bu sembol adı için IL okuma veya yazma talimatları yayınlamayı bilmelidir.

'Ağır kaldırma', IL'nin belirli bir donanım mimarisinde çalışmasını sağlamaktan sorumlu çekirdek CLR tarafından yapılır.

Bu aynı zamanda özniteliği neden uygun olmayan (statik olmayan) bir sembol üzerine koymanın derleyiciden bir tepki almadığını da açıklar. Derleyici, özelliğin hangi özel semantiği gerektirdiğini bilmiyor. Bununla birlikte, FX / Cop gibi kod analiz araçları bunu bilmelidir.

Bakmanın başka bir yolu: CIL, bir dizi depolama kapsamı tanımlar: statik (global) depolama, üye depolama ve yığın depolama. TLS bu listede değil, büyük olasılıkla TLS'nin bu listede olması gerekmiyor. Sembol bir TLS özelliğiyle etiketlendiğinde IL okuma ve yazma talimatları TLS'ye erişmek için yeterliyse, IL'nin neden TLS için özel bir temsili veya tedavisi olmalıdır? Gerek yok.


Ancak TLS'nin bu özel, uygulamaya özgü davranışı .NET / CLR'nin "doğrulanabilir" satış noktasını tamamen bozmuyor mu?
Dai

116

[ThreadStatic] özelliği nasıl çalışır?

ThreadStatic ile işaretli alanın bir iş parçacığına bağlı olduğunu ve ömrünün bir iş parçacığının ömrü ile karşılaştırılabilir olduğunu düşünebilirsiniz .

Yani sözde kodda ThreadStatic(anlambilime göre) bir iş parçacığına anahtar / değer çiftinin eklenmesine benzer:

Thread.Current["MyClass.myVariable"] = 1;
Thread.Current["MyClass.myvariable"] += 1;

ancak sözdizimi biraz daha kolaydır:

class MyClass {
  [ThreadStatic]
  static int myVariable;
}
// .. then
MyClass.myVariable = 1;
MyClass.myVariable += 1;

statik olmayan bir üyeye koyarsanız ne olur?

Göz ardı edildiğine inanıyorum:

    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);
    }

Ek ThreadStaticolarak, normal statik alanlara kıyasla herhangi bir senkronizasyon mekanizması gerektirmediğini belirtmek gerekir (çünkü durum paylaşılmaz).


1
Sahte kod gibi ikinci olmalı "MyClass.myVariable", değil mi?
akshay2000

Kesin kısıtlamalardan emin değilim, ancak ilkel bir tür olması gerekmediği açık değilse işaret etmek istedim. Kaynağa bakarsanız TransactionScope, kapsam için her türlü şeyi orada saklarlar ( referenceource.microsoft.com/#System.Transactions/System/… )
Simon_Weaver 27:17

10

[ThreadStatic] her bir iş parçacığında aynı değişkenin izole edilmiş versiyonlarını oluşturur.

Misal:

[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();
}

3

[ThreadStatic]İle işaretli alan , Yerel İş Parçacığı Depolama Alanı'nda oluşturulur, böylece her iş parçacığının alanın kendi bir kopyası olur, yani alanların kapsamı iş parçacığı için yereldir.

TLS alanlarına gs / fs bölümleri kayıtları aracılığıyla erişilir. Bu bölümler OS çekirdeği tarafından iş parçacığına özgü belleğe erişmek için kullanılır. OS çekirdeği tarafından yapılır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.