Zrozumienie pul wątków w C #

Wątek to najmniejsza jednostka wykonania w procesie. Pula wątków składa się z wielu wątków lub, mówiąc dokładniej, zbioru wątków i może służyć do wykonywania kilku czynności w tle.

Dlaczego powinienem używać pul wątków?

Wątki są drogie, ponieważ zużywają wiele zasobów w systemie na potrzeby inicjalizacji, przełączania kontekstów i zwalniania zajmowanych zasobów. Zwykle, gdy wątek wykonuje operację we / wy (obsługa plików, operacja bazy danych lub dostęp do zasobów sieciowych itp.), Wątek jest blokowany przez system operacyjny aż do zakończenia operacji we / wy. Wątek wznowi działanie procesora po zakończeniu operacji we / wy.

Pula wątków to dobry wybór, gdy chcesz ograniczyć liczbę wątków działających w danym momencie i chcesz uniknąć obciążenia związanego z tworzeniem i niszczeniem wątków w aplikacji. Jest to również dobry wybór, gdy masz w aplikacji wiele zadań, które muszą być wykonywane równolegle lub współbieżnie, a chcesz poprawić responsywność aplikacji, unikając przełączników kontekstu. Aby utworzyć pulę wątków, możesz skorzystać z klasy System.Threading.ThreadPool.

Poniższy fragment kodu pokazuje, jak ustawić minimalną liczbę wątków w puli wątków.

ThreadPool.SetMinThreads (50, 50);

Należy jednak pamiętać, że gdy długo działające zadanie jest wykonywane, wątek puli wątków może być blokowany przez długi czas. Co gorsza, przychodzące żądania, które zależą od wątków z puli wątków, mogą być wstrzymane lub nawet mogą zostać odrzucone głównie dlatego, że pula wątków może nie mieć dostępnych wątków do obsługi żądania przychodzącego. Pula wątków nie jest również dobrym wyborem, gdy masz wątki różniące się priorytetami lub może być konieczne przedwczesne przerwanie wątku. Przedwczesne zakończenie wątku oznacza, że ​​wątek został zatrzymany na siłę przed upływem czasu jego zwrotu.

Jak działa pula wątków?

Zasadniczo podczas pracy z pulami wątków zazwyczaj tworzy się kolekcję wątków i przechowuje je w puli wątków przed użyciem wątków w aplikacji. Gdy potrzebujesz wątku, będziesz ponownie używać tych wątków, zamiast tworzyć nowe wątki za każdym razem, gdy aplikacja będzie musiała użyć wątku.

Tak więc aplikacja wysłałaby żądanie do puli wątków, aby pobrać z niej wątek, wykonać działania przy użyciu wątku, a po zakończeniu zwracać wątek z powrotem do puli wątków. Pule wątków są pomocne w sytuacjach, gdy w aplikacji jest więcej zadań do wykonania niż tworzenie wątków (istnieje ograniczenie maksymalnej liczby wątków, które można utworzyć na proces).

Jak mogę zoptymalizować pulę wątków?

Po uruchomieniu procesu jest przydzielana pula wątków przez środowisko CLR. Pamiętaj, że w razie potrzeby możesz skonfigurować rozmiar puli wątków. Środowisko uruchomieniowe inteligentnie zarządza pulą wątków. Po uruchomieniu puli wątków w puli wątków jest tylko jeden wątek. Od tego momentu menedżer puli wątków (komponent odpowiedzialny za zarządzanie pulą wątków) tworzy więcej wątków i przechowuje je w puli wątków wraz ze wzrostem obciążenia aplikacji, tj. Aplikacja potrzebuje coraz większej liczby zadań wykonywanych jednocześnie.

Liczba wątków, które mogą być dostępne w puli wątków w dowolnym momencie, zależy od maksymalnego dopuszczalnego limitu wątków w puli wątków. Innymi słowy, liczba dostępnych wątków w puli wątków zmienia się od czasu do czasu w zależności od wykorzystania wątków przez aplikację. Po osiągnięciu maksymalnego limitu (maksymalnej liczby wątków w puli wątków) aplikacja tworzy nowe wątki znacznie rzadziej.

W razie potrzeby zawsze możesz samodzielnie ustawić górny limit dopuszczalnych wątków w puli wątków. Aby to zrobić, należy skorzystać z właściwości ThreadPool.SetMaxThreads. Aby ustawić dolny limit wątków w puli wątków, można użyć właściwości ThreadPool.SetMinThreads. Domyślny dolny limit liczby wątków w puli wątków to jeden wątek na procesor.