Aracılığıyla paylaş


TLS Kuralları ve Sınırlamaları

Aşağıdaki yönergeler statik olarak bağlı iş parçacığı yerel nesneleri ve değişkenleri bildirilirken incelenmelidir:

  • thread özniteliği sadece veri bildirimlerine ve tanımlarına uygulanabilir. İşlev bildirimlerinde veya tanımlarında kullanılamaz. Örneğin, aşağıdaki kod örneği derleyici hatası üretir:

    #define Thread  __declspec( thread )
    Thread void func();     // This will generate an error.
    
  • thread değiştiricisi static uzantısıyla sadece veri öğelerinde belirtilebilir. Bu C++ sınıflarının genel veri nesnelerini (hem static hem de extern), yerel statik nesneleri ve statik veri üyelerini içerir. Otomatik veri nesneleri thread özniteliği ile bildirilemezler. Aşağıdaki kod derleyici hataları üretir:

    #define Thread  __declspec( thread )
    void func1()
    {
        Thread int tls_i;            // This will generate an error.
    }
    
    int func2( Thread int tls_i )    // This will generate an error.
    {
        return tls_i;
    }
    
  • İş parçacığı yerel nesnesinin bildirimleri ve tanımının hepsi thread özniteliğini belirtmelidir. Örneğin, aşağıdaki kod hata üretir:

    #define Thread  __declspec( thread )
    extern int tls_i;        // This will generate an error, since the
    int Thread tls_i;        // declaration and definition differ.
    
  • thread özniteliği tür değiştiricisi olarak kullanılamaz. Örneğin, aşağıdaki kod örneği derleyici hatası üretir:

    char __declspec( thread ) *ch;        // Error
    
  • C++ sınıfları thread özniteliğini kullanamazlar. Ancak, C++ sınıf nesnelerinin thread özniteliği ile birlikte örnekleri oluşturulabilir. Örneğin, aşağıdaki kod örneği derleyici hatası üretir:

    #define Thread  __declspec( thread )
    class Thread C       // Error: classes cannot be declared Thread.
    {
    // Code
    };
    C CObject;
    

    thread özniteliğini kullanan C++ nesne bildirimlerine izin verildiğinden, aşağıdaki iki örnek anlam olarak eşdeğerdir:

    #define Thread  __declspec( thread )
    Thread class B
    {
    // Code
    } BObject;               // OK--BObject is declared thread local.
    
    class B
    {
    // Code
    };
    Thread B BObject;        // OK--BObject is declared thread local.
    
  • İş parçacığı yerel nesne adresi sabit olarak düşünülmez ve böyle bir adres içeren herhangi bir ifade sabit ifade olarak düşünülmez. Standart C'de, bunun etkisi iş parçacığı yerel değişken adresini nesne veya işaretçi için başlatıcı olarak kullanmayı yasaklamaktır. Örneğin, aşağıdaki kod C derleyicisi tarafından hata olarak işaretlenmiştir:

    #define Thread  __declspec( thread )
    Thread int tls_i;
    int *p = &tls_i;       //This will generate an error in C.
    

    Bu kısıtlama C++'ta geçerli değildir. C++ bütün nesnelerin dinamik başlangıcına izin verdiğinden, bir nesneyi iş parçacığı yerel değişkeni adresini kullanan bir ifadeyi kullanarak başlatabilirsiniz. Bu iş parçacığı yerel nesnelerinin yapımına benzer bir şekilde sağlanır. Örneğin, daha önce gösterilen kod C++ kaynak dosyası olarak derlendiğinde hata üretmiyordu. İş parçacığı yerel değişken adresinin, adresi alınan iş parçacığı var olduğu sürece geçerli olduğunu unutmayın.

  • Standart C, kendilerine başvuru içeren ifadelerle nesnelerin veya değişkenlerin başlangıcına izin verir, ancak sadece statik olmayan uzantı nesneleri için. C++ genelde, kendilerine başvuru içeren ifadelerle nesnelerin bu tür başlangıcına izin verirken, iş parçacığı yerel nesneleriyle bu tür başlangıçlara izin verilmez. Örneğin:

    #define Thread  __declspec( thread )
    Thread int tls_i = tls_i;                // Error in C and C++ 
    int j = j;                               // OK in C++, error in C
    Thread int tls_i = sizeof( tls_i )       // Legal in C and C++
    

    Başlatılan nesneyi içeren sizeof ifadesinin kendisine bir başvuru göstermediğine ve hem C'de hem de C++'ta etkin olduğuna dikkat edin.

    İş parçacığı yerel depolama hizmetindeki ilerde yapılacak olan muhtemel geliştirmeler sebebiyle, C++ bu şekildeki dinamik iş parçacığı başlangıçlarına izin vermez.

  • Windows Vista'dan önceki Windows işletim sistemlerinde, __declspec'in (iş parçacığı) baz kısıtlamaları vardı. DLL verileri veya nesneleri __declspec( iş parçacığı ) olarak bildirirse, dinamik olarak yüklenmişse koruma hatalarına sebep olabilir. DLL LoadLibrary ile yüklendikten sonra, kod __declspec( iş parçacığı ) verisine başvurursa sistem hatasına sebep olur. İş parçacığı için genel değişken yeri çalışma zamanında ayrıldığından, bu yerin büyüklüğü uygulamanın gereksinimlerinin ve statik olarak bağlı olan bütün DLL'lerin gereksinimlerinin hesaplanmasına bağlıdır. LoadLibrary kullandığınızda, __declspec( iş parçacığı ) ile bildirilen iş parçacığı yerel değişkenleri için bu alanı genişletemezsiniz. Eğer DLL LoadLibrary ile yüklenmişse, TLS ayırmak için DLL'nizde TlsAlloc gibi TLS API'larını kullanın.

Ayrıca bkz.

Kavramlar

İş Parçacığı Yerel Depolaması (TLS)