[ Pobierz całość w formacie PDF ]
.TlsFree ()Zwalnia indeks dla danego procesu w tablicy danych w¹tków.TlsGetValue () Dla bie¿¹cego w¹tku odczytuje zawartoœæ wskazanej pozycji w danych egzemplarza w¹tku.TlsSetValue ()Dla bie¿¹cego w¹tku ustawia zawartoœæ wskazanej pozycji w danych egzemplarza w¹tku.Gdy alokowany jest lokalny obszar danych w¹tku (wywo³aniem TlsAlloc ()), zwracany jest indeks do tablic danych w¹tku.Ten indeks musi zostaæ przechowany w obszarze pamiêci wspólnej dla w¹tków, czyli najprawdopodobniej w zmiennych globalnych.W tym momencie mo¿na ju¿ dynamicznie zaalokowaæ dane w¹tku, zaœ wskaŸnik do tych danych bêdzie przechowywany w lokalnych danych w¹tku.Drugim rodzajem danych prywatnych dla w¹tku s¹ statyczne lokalne dane w¹tku.S¹ one najprostsze w u¿yciu, gdy¿ - po zadeklarowaniu - wygl¹daj¹ jak zmienne globalne.W rzeczywistoœci, kompilator i program ³aduj¹cy wspó³pracuj¹ ze sob¹ w celu automatycznego zaalokowania nowego zestawu danych dla ka¿dego w¹tku tworzonego w ramach procesu.A jeœli sprawdzisz kod asemblera wygenerowany przez kompilator w celu dostêpu do tych danych, ujrzysz dodatkowe instrukcje stanowi¹ce dodatkowy poœredni poziom w stosunku do kodu odwo³uj¹cego siê do zwyk³ych danych.Jednak ca³e piêkno statycznych lokalnych danych w¹tku polega w³aœnie na tym, ¿e mimo i¿ wygl¹daj¹ jak zmienne lokalne, s¹ danymi prywatnymi dla w¹tku.Kluczem do statycznych lokalnych danych w¹tku jest para s³Ã³w kluczowych specyficznych dla kompilatora Microsoft C: _dêci spec oraz thread.Oto jak mo¿na zdefiniowaæ wartoœæ ca³kowit¹ prywatn¹ dla w¹tku:_declspec (thread) int i = 0;Wszystkie s³owa kluczowe kompilatora rozpoczynaj¹ce siê od znaku podkreœlenia (_) reprezentuj¹ s³owa kluczowe nie nale¿¹ce do standardu ANSI C/C++.W przesz³oœci Microsoft dowolnie dodawa³ do swojego kompilatora nowe deklaracje: _pascai, _cdecl, _near, _far, _stdcall itd.Jednak w koñcu móg³ pojawiæ siê problem, jeœli któraœ z takich deklaracji zaczê³aby kolidowaæ z nowymi s³owami kluczowymi, które sta³yby siê czêœci¹ standardu C++.W celu kontrolowania tworzenia nowych deklaratorów Microsoft stworzy³ pojedynczy, ogólny deklarator: _dêci spec.Ma on pe³niæ rolê g³Ã³wnego deklaratora.Wszystkie nowe rozszerzenia kompilatora - takie jak statyczne lokalne dane w¹tków - bêd¹ dostêpne przez u¿ycie modyfikatorów g³Ã³wnego deklaratora.Obecnie wiemy jedynie o trzech innych specyfikacjach deklaratora: dl l import, dllexport oraz naked.W razie potrzeby zostan¹ stworzone kolejne rozszerzenia kompilatora.Aby uczyniæ deklaracjê statycznej lokalnej danej w¹tku nieco bardziej czyteln¹, stwórz symbol preprocesora:#define THREADDATA _declspec (thread)Poprzednia deklaracja zmiennej ca³kowitej prywatnej dla w¹tku teraz przyjmie nieco bardziej czyteln¹ formê:THRADDATA int i = 0;Dane prywatne dla w¹tku musz¹ byæ zainicjowane.W poprzednim przyk³adzie ustawialiœmy wartoœæ ca³kowit¹ na zero.Choæ to niewielka ró¿nica dla programisty, jednak dla kompilatora ma du¿e znaczenie, gdy¿ traktuje on zainicjowane dane zupe³nie inaczej ni¿ dane niezainicjowane.Obecna wersja kompilatora dopuszcza jedynie zainicjowane lokalne dane w¹tku.Ta ma³a ró¿nica zapewnia, ¿e otrzymujesz potrzebne wsparcie w obs³udze danych.(W dalszej czêœci rozdzia³u, przy omawianiu wspólnych danych, powiemy równie¿ dlaczego tak¿e globalne dane musz¹ byæ zainicjowane, aby mog³y byæ udostêpniane pomiêdzy procesami).Jak ju¿ wspomnieliœmy, g³Ã³wn¹ zalet¹ tego rodzaju prywatnych danych w¹tku jest to, ¿e wygl¹daj¹ jak zwyk³e zmienne globalne.Po zdefiniowaniu nie musisz ju¿ korzystaæ z wywo³añ API w celu dostêpu do danych: one po prostu s¹.Jeœli przyjrzysz siê kodowi maszynowemu u¿ytemu przy odwo³aniach do tych danych, zauwa¿ysz, ¿e zawiera on pewne dodatkowe instrukcje.Jednak gdy potrzebujesz danych lokalnych dla w¹tku, jest to doœæ niska cena.Kolejn¹ zalet¹ tego rodzaju prywatnych danych w¹tku jest to, ¿e mo¿esz alokowaæ tyle danych, ile potrzebujesz.Choæ w tym przyk³adzie pokazaliœmy alokowanie pojedynczej zmiennej, nie ma problemu z alokowaniem tysiêcy czy nawet dziesi¹tek tysiêcy bajtów.Zmienne alokowane prywatnie dla w¹tku s¹ umieszczane we w³asnych sekcjach pliku wykonywalnego.Tak wiêc, podobnie jak inne sekcje danych lub kodu, mog¹ w miarê potrzeby rozci¹gaæ siê na wiele megabajtów.Jednak statyczne dane lokalne w¹tku posiadaj¹ jedno ograniczenie.Nie mog¹ byæ u¿ywane w bibliotekach DLL dynamicznie ³adowanych do pamiêci.Jeœli program w celu jawnego za³adowania biblioteki DLL do pamiêci wywo³uje funkcjê LoadLibraryo, statyczne lokalne dane w¹tku nie mog¹ byæ u¿ywane.Przyk³adem bibliotek DLL w ten sposób ³adowanych do pamiêci s¹ sterowniki urz¹dzeñ dla drukarek.W przypadkustatycznie ³adowanych bibliotek DLL statyczne lokalne dane w¹tku dzia³aj¹ bez problemów.Takie biblioteki DLL s¹ ³adowane do pamiêci w momencie uruchamiania wywo³uj¹cego pliku wykonywalnego.Poza tym ograniczeniem statyczne lokalne dane w¹tku s¹ doskona³¹ metod¹ powi¹zania danych aplikacji z w¹tkami systemowymi.Na tym koñczymy omawianie pamiêci prywatnej dla procesu.Teraz skierujemy uwagê na wszystkie rodzaje pamiêci, które mog¹ byæ wspólnie wykorzystywane przez ró¿ne procesy.Pamiêæ wspólnaPozosta³¹ czêœæ rozdzia³u poœwiêcimy tej czêœci Win32 API, która zwi¹zana jest z alokowaniem pamiêci wspólnej - czyli pamiêci dostêpnej dla dwóch lub wiêcej procesów jednoczeœnie.Jak dot¹d zajmowaliœmy siê alokowaniem pamiêci prywatnej.Pamiêæ prywatna jest zdecydowanie bardziej wa¿na, gdy¿ wiêkszoœæ danych procesu to dane prywatne.Byæ mo¿e w³aœnie z tego powodu Win32 zawiera wiêcej funkcji zwi¹zanych z pamiêci¹ prywatn¹ ni¿ zwi¹zanych z pamiêci¹ wspóln¹.Wa¿n¹ zalet¹ korzystania z prywatnej pamiêci jest to, ¿e zwiêksza ona stabilnoœæ systemu.Poniewa¿ zmniejsza ryzyko, ¿e jedna aplikacja nadpisze obszar pamiêci innej aplikacji, w³aœnie taka pamiêæ jest domyœlnie alokowana dla procesu.Aby móc udostêpniæ pamiêæ, aplikacja musi tego jawnie za¿¹daæ.Dla twórcy aplikacji ró¿nica pomiêdzy pamiêci¹ wspóln¹ a prywatn¹ jest wzglêdna.W koñcu dane, które w jakiejœ chwili s¹ prywatne dla procesu, za moment mog¹ byæ ju¿ udostêpniane.Jednak dla systemu operacyjnego ta ró¿nica jest wa¿na i zasadnicza.Jak ju¿ wspominaliœmy, Win32 API uwypukla tê ró¿nicê oferuj¹c dwie funkcje do tworzenia przestrzeni adresowych: virtualAlloc() dla prywatnej przestrzeni adresowej i MapView-of File () dla pamiêci wspólnej
[ Pobierz całość w formacie PDF ]