2012-06-12 11 views

Odpowiedz

12

Pamięć lokalna wątku dotyczy tylko zmiennych statycznych. Nie ma sensu, aby struktura niestatyczna lub członkowie klasy mieli wątek lokalny.

Zmienne lokalne (automatyczne) są zawsze specyficzne dla wątku, który wykonuje kod, ale globalne i statyczne zmienne są współużytkowane przez wątki, ponieważ znajdują się w segmencie danych lub BSS. TLS zapewnia mechanizm, dzięki któremu te globalne zmienne są lokalne dla wątku i to właśnie osiąga słowo __thread - instruuje kompilator, aby utworzył osobną kopię zmiennej w każdym wątku, podczas gdy leksykalnie pozostaje globalnym (np. Można uzyskać do niego dostęp przez różne funkcje wywoływane w ramach tego samego wątku wykonywania).

Niestateczne klasy i elementy konstrukcyjne są umieszczane w tym samym miejscu, w którym obiekt (klasa lub struktura) jest alokowany - na stosie, jeśli zadeklarowana jest zmienna automatyczna lub w sterty, jeśli użyto new lub malloc(). Tak czy inaczej, każdy wątek otrzymuje unikalne miejsce do przechowywania zmiennej, a __thread po prostu nie ma zastosowania w tym przypadku, stąd pojawia się błąd kompilatora.

+6

Nie z aktualnym znaczeniem __thread lub thread_local, ale istnieje wiele sytuacji, w których sensowne jest posiadanie innego elementu dla każdego wątku, ładnie zapakowanego za jakimś interfejsem. – PlasmaHH

+9

Muszę się nie zgadzać - tylko dlatego, że obiekt jest tworzony przez pojedynczy wątek, nie oznacza to, że będzie on manipulowany wyłącznie przez jeden wątek (na przykład struktury danych bez blokady). Wprawdzie jest to jednak stosunkowo rzadkie. – Cameron

+0

Byłbym wdzięczny, gdyby któryś ze spadkobierców chciał opublikować contra-przykład lub lepszą odpowiedź, lub dostarczyć sugestie, jak edytować pytanie lub samodzielnie edytować pytanie. –

6

gcc narzuca następujące restrictions sprawie wykorzystania __thread:

__thread specifier może być stosowana do wszystkich globalnych, statyczne, funkcja-scoped statyczne lub danych statycznych podzbioru-scoped Urządzony klasa. Nie można go zastosować do automatycznego lub statycznego elementu danych o ograniczonym zakresie.

Modyfikator __thread jest obsługiwany przez wiele kompilatorów. Nie jest wykluczone, że dokładne ograniczenia różnią się nieco od kompilatora do kompilatora.

0

Zgodnie ze starą książką Petzolda "Programowanie systemu Windows" (strona 1241) oznacza się zmienną jako wątek lokalny za pomocą słów kluczowych: __declspec (wątek). Na przykład: __declspec (wątek) int iGlobal = 1;

Wątpię, czy można to zrobić na zajęciach. Możesz także ustawić zmienną statyczną. [edytuj] po prostu zdałam sobie sprawę, że prawdopodobnie nie używasz systemu Windows ... Tak więc dla każdego, kto potrzebuje odpowiedzi Windows, może to być istotne.

4

C11 standardowy Sekcja 6.7.1 Ustęp 2

Co najwyżej jeden przechowywania klasy specifier mogą być podane w specyfikatorami zgłoszenia w deklaracji , oprócz tego, że może pojawić się z _Thread_local statyczne lub extern. 120)

Standard C11 Rozdział 6.7.1 Ustęp 3

W zgłoszeniu obiektu z zakresu bloku jeśli Specyfikatory deklaracji obejmują _Thread_local, ale obejmuje również zarówno statyczne extern. Jeśli _Thread_local pojawia się w dowolnej deklaracji obiektu, musi być obecna w każdej deklaracji tego obiektu o wartości _Thread_local.

+1

Chyba masz na myśli C11, nie? C99 nie miało modelu wątku i tak dalej. –

+0

Poprawione. Nawyk pisania C99. – phoxis

0

Dla C to nie ma większego sensu, członkowie static (= global) są tylko cechą C++. Tak więc nowy standard C11 (który wprowadza _Thread_local) nie pozwala na to. Te bestie są dozwolone w zasadzie wszędzie, gdzie dozwolona jest zmienna o statycznym czasie przechowywania.

Dla C++ może to mieć sens w klasie jako analogiczny do członka static, ale jeśli jest to dozwolone przez C++ 11, nie mam pojęcia.

+0

Nie wydaje mi się to dozwolone, mam C2720 z VS2015: https://msdn.microsoft.com/en-us/library/w8x1t4f0.aspx –

1

należy zmienić __thread int tl; do thread_local static int tl;

+1

Wtedy nie można mieć wielu instancji klasy/klasy mających różne wartości w to pole. – rustyx

Powiązane problemy