Uwaga: wszędzie tam, gdzie wspominam, thread
mam na myśli wątki w Pythonie, dopóki nie zostanie to wyraźnie określone.
Wątki działają trochę inaczej w Pythonie, jeśli przechodzisz z C/C++
tła. W Pythonie tylko jeden wątek może być uruchomiony w danym momencie, co oznacza, że wątki w Pythonie nie mogą w pełni wykorzystać mocy wielu rdzeni przetwarzających, ponieważ z założenia nie jest możliwe, aby wątki działały równolegle na wielu rdzeniach.
Ponieważ zarządzanie pamięcią w Pythonie nie jest bezpieczne dla wątków, każdy wątek wymaga wyłącznego dostępu do struktur danych w interpreterze Pythona, który jest uzyskiwany przez mechanizm o nazwie (globalna blokada interpretr) .GIL
Why does python use GIL?
Aby zapobiec jednoczesnemu dostępowi wielu wątków do stanu interpretera i uszkodzeniu stanu interpretera.
Chodzi o to, że za każdym razem, gdy wątek jest wykonywany (nawet jeśli jest to główny wątek) , uzyskiwany jest GIL i po pewnym predefiniowanym przedziale czasu GIL jest zwalniany przez bieżący wątek i ponownie pobierany przez inny wątek (jeśli istnieje).
Why not simply remove GIL?
Nie jest tak, że niemożliwe jest usunięcie GIL-a, po prostu w trakcie wykonywania tego w końcu umieszczamy wiele blokad wewnątrz interpretera w celu serializacji dostępu, co sprawia, że nawet pojedyncza aplikacja wątkowa jest mniej wydajna.
więc koszt usunięcia GIL jest opłacany przez zmniejszoną wydajność aplikacji jednowątkowej, co nigdy nie jest pożądane.
So when does thread switching occurs in python?
Zmiana wątku następuje po wydaniu GIL. Więc kiedy GIL zostanie wydany? Należy wziąć pod uwagę dwa scenariusze.
Jeśli wątek wykonuje operacje związane z procesorem (przetwarzanie obrazu Ex).
W starszych wersjach Pythona przełączanie wątków występowało po ustalonej liczbie instrukcji Pythona, domyślnie było ustawione na 100
. Okazało się, że nie jest to zbyt dobra polityka decydowania o przełączeniu, ponieważ czas spędzony na wykonywaniu pojedynczej instrukcji może bardzo szalenie od milisekundy do nawet sekundy, dlatego zwalnianie GIL po każdej 100
instrukcji, niezależnie od czasu jej wykonania, jest złą polityką.
W nowych wersjach zamiast używania liczby instrukcji jako metryki przełączania wątku, używany jest konfigurowalny przedział czasu. Domyślny interwał przełączania to 5 milisekund. Bieżący interwał przełączania można uzyskać za pomocą sys.getswitchinterval()
. Można to zmienić za pomocąsys.setswitchinterval()
Jeśli wątek wykonuje operacje związane z operacjami we / wy (dostęp do systemu plików Ex lub we /
wy sieci)
GIL jest wydawany, gdy wątek czeka na zakończenie operacji we / wy.
Which thread to switch to next?
Interpreter nie ma własnego harmonogramu, a który wątek zostanie zaplanowany na koniec interwału, jest decyzją systemu operacyjnego. .