2010-09-17 12 views
10

W jaki sposób kompilator języka C++ implementuje lokalne przechowywanie wątków w C++ 0xW jaki sposób kompilator C++ implementuje pamięć lokalną wątku w C++ 0x?

Przeszukałem to w google. Ale nie mogę nic na ten temat znaleźć.

Czy ktoś ma jakiekolwiek materiały na ten temat?

+0

Standard C++ ma zero (lub bardzo niewiele) szczegółów implementacji. –

+0

To może teraz pomóc: http://www.akkadia.org/drepper/tls.pdf –

Odpowiedz

13

Czytanie z Wikipedia entry.

Lokalna pamięć wątku nie jest czymś, co jest szczególnie ważne w C++. Czasami działa pod różnymi nazwami, np. "TLS" (tylko skrót lokalnej pamięci wątku) lub "pamięć specyficzna dla wątków" (TSS).

Większość systemów operacyjnych zapewnia interfejsy API do uzyskiwania dostępu do pamięci wątków. Na przykład system Windows ma numer bunch of API functions rozpoczynający się od "TLS". Pod maską system Win32 rezerwuje specjalny obszar dla różnych danych dotyczących wątków, w tym magazynu lokalnego dla wątków użytkownika, dostępnego przez konkretny rejestr CPU (FS na x86). Linux zapewnia pamięć specyficzną dla wątków za pośrednictwem interfejsów API pthread o nazwach takich jak pthread_key_create i są one zazwyczaj implementowane przy użyciu podobnej techniki.

Jest możliwe, że system operacyjny nie zapewnia żadnego wsparcia. Jeśli jednak system operacyjny dostarcza unikalny dla procesu identyfikator wątku za pośrednictwem interfejsu API, wówczas biblioteka środowiska wykonawczego C++ może wewnętrznie konserwować coś konceptualnie, jak w przypadku modelu std::map<thread_id, per_thread_storage>. Oczywiście, istnieje problem z tym, co jest per_thread_storage. Jeśli program był statycznie połączony, może to być po prostu coś w rodzaju wskaźnika do dużej struktury z wszystkimi zmiennymi pamięciowymi lokalnymi wątku zadeklarowanymi w programie jako elementy. To uproszczenie, ale masz ogólny pomysł.

Uzyskiwanie dostępu do lokalnych zmiennych pamięciowych wątku nie jest oczywiście prostą pamięcią do odczytu lub zapisu. Jest potencjalnie bardziej zaangażowany niż to. Jeśli zamierzasz używać wątku lokalnego/specyficznego dużo w konkretnej funkcji, polecam najpierw skopiować lokalny wskaźnik przechowywania wątku do zmiennej lokalnej.

+2

Odpowiedziałeś na pytanie, w jaki sposób programista aplikacji może implementować protokół TLS, ale nie w jaki sposób kompilator i program ładujący obsługują C++ 0x klucz_lokalny thread_local – doron

+6

@ doron: Kompilator i program ładujący używają interfejsów API dostarczonych przez system operacyjny lub wykonują coś równoznacznego z techniką mapowania, bez konieczności pisania kodu przez programistę aplikacji. – Doug

4

Zmienne globalne (lub zapisywalne dane statyczne - WSD) są zwykle przechowywane w bloku pamięci oddzielonym od stosu, sterta i kodu. Blok WSD jest tworzony i inicjowany przed uruchomieniem kodu wykonywalnego.

C++ 0x wprowadza słowo kluczowe thread_local, które zapewnia utworzenie oddzielnej instancji zmiennej globalnej dla jednego wątku. Problem polega na tym, że w każdym wątku musi być załadowany inny blok.

Kolejna trudność polega na tym, że adres zmiennej nie jest ustalony w czasie połączenia i jest różny dla każdego wątku.

Istnieją dwa sposoby obejścia tego problemu. Jednym z nich jest, aby kompilator wygenerował wywołanie funkcji w celu uzyskania właściwego bloku, podczas gdy drugi ma zmienić ABI, aby przechowywać blok TLS w jednym z rejestrów procesorów. Można go następnie użyć z przesunięciami, aby uzyskać dostęp do poprawnej zmiennej thread_local.

Różni się to od obsługi bibliotek, w której system operacyjny przechowuje pojedynczą wartość void*, której można użyć, przechowuje wskaźnik do lokalnego bloku wątków, który został przydzielony na stercie procesu.

Jeśli chcesz poznać szczegóły, zobacz here.

0

Możesz używać boost::thread do przenośnego obsługiwania TLS na różnych platformach. Implementacja każdej z nich jest zawarta w kodzie i powinna pomóc zrozumieć, w jaki sposób różne systemy obsługują ten obszar.

+1

W C++ 0x kompilator obsługuje TLS ze słowem kluczowym thread_local – doron

+0

Używanie boost jest w porządku, ale dla rekordu niektóre kompilatory rzeczywiście kupiły w przestrzeni problemu. http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html –

+0

Masz rację, zaktualizuję to. –

Powiązane problemy