2013-06-04 18 views
13

Czytam i uczę się o ThreadScheduler oraz artykułach dotyczących zadań i natknąłem się na funkcję ThreadPool.UnsafeQueueUserWorkItem używaną w jednym z MSDN examples na temat własnych aplikacji ThreadSchedulers. W MSDN description about UnsafeQueueUserWorkItem istnieje duże ostrzeżenie, że funkcja może być luką bezpieczeństwa i że "nie propaguje stosu wywołującego".UnsafeQueueUserWorkItem i co dokładnie oznacza "nie propaguje stos wywołujący"?

Jedynym linkiem jest QueueUserWorkItem, który - od nazwy - wydaje się być "bezpiecznym odpowiednikiem"? ale nie wspomina nic o wywoływaniu stosów.

Co to właściwie znaczy propagować stos? Skopiuj go przed rozpoczęciem pracy? Dlaczego inny wątek i tak wymaga stosu wątku wywołującego? Zakładam, że zaczynają od świeżego i pustego stosu. W końcu, gdy funkcja wątku powraca, nie kontynuuje wykonywania funkcji planowania zadania, prawda?

Odpowiedz

16

Jest to szczegół implementacji CAS, Code Access Security. Które może sprawdzić, czy wątek ma wystarczające uprawnienia do wykonania operacji. Ma to znaczenie tylko wtedy, gdy kod działa w ograniczonym środowisku zabezpieczeń, nie działa z pełnym zaufaniem lub w piaskownicy.

Instalacja hydrauliczna, która umożliwia taką pracę, jest skomplikowana i mogę tylko przybliżać jej działanie. Klasa ExecutionContext jest kluczowa, określa kontekst zabezpieczeń, w którym działa kod. Sprawy stają się trudne, gdy wątek uruchamiany z ograniczonymi prawami rozpoczyna kolejny wątek. Oczywiście, że inny wątek musi działać z takimi samymi ograniczeniami jak oryginalny wątek. CAS zależy od możliwości wykonywania spacerów na stosach w celu wykrycia ograniczeń. To trudne w innym wątku, ma własny stos.

Metoda ExecutionContext.Capture() pełni tutaj istotną rolę. Tworzy kopię kontekstu wątku wywołującego, w tym przechodzenie do stosu w celu utworzenia "skompresowanego" stosu odkrytych atrybutów bezpieczeństwa. Nowy wątek jest następnie uruchamiany z przechwyconym kontekstem.

ThreadPool.UnsafeQueueUserWorkItem() pomija wywołanie Capture(). Wątek threadpool będzie działał z domyślnym kontekstem wykonania.

To jest optymalizacja, Capture() nie jest tanią metodą. Ma to znaczenie w rodzaju programu, który zależy od wątków TP, aby szybko wykonać zadania. Serwer internetowy przeskakuje do głowy. Również rodzaj kodu, który używa metody, widać na przykład w wewnętrznych metodach w przestrzeni nazw System.Net.

Oczywiście jest to niebezpieczne, nie działa z ograniczeniami CAS wątku źródłowego.

+1

Ah, rozumiem. Bardzo interesujące. Teraz ... czy ma to jakąś różnicę wydajności, gdy _nie_ działa w jakimkolwiek środowisku bezpieczeństwa? – Imi

+0

Nie tak jak to działa, kontrole CAS są zawsze wykonywane. Stos spacerów ma stały koszt, który zależy od głębokości stosu. "Koszt" to wielkie słowo, mówimy tutaj o kilku mikrosekundach. Nie ma to znaczenia, dopóki nie uruchomisz * tysięcy * żądań wątku TP na sekundę. –

+0

_Mówimy o garstce mikrosekund tutaj_ Woah .. dzięki za komentarz. W takim razie lepiej wyprofiluj mój prototyp niestandardowego programu planującego wątek. Zdecydowanie nie mogę _nie żyć z czymś w zakresie "mikrosekund". – Imi

Powiązane problemy