2012-10-25 12 views
5

My wprowadzamy naszą pierwszą aplikację django pod mod_wsgi jakCzy django + mod_wsgi wymaga dyscypliny programowania z wątkami?

`WSGIDaemonProcess our-appname processes=6 threads=15'` 

a my o dyskusji na temat tego, czy naszym kodzie Python i bibliotek Redis i PostgreSQL to używa musi być bezpieczny wątku, czy nie.

Z tego co mogę powiedzieć po przeczytaniu dokumentacji mod_wsgi, mimo że pracownik apache przetwarza żądania z wieloma apache wątków, nasz python kod jest dla wszystkich zamiarów i celów jednowątkowym. Nie widzę ostrzeżeń na dokumentach mod_wsgi z napisem "Uwaga! Musisz się teraz martwić o globalne dane i bezpieczeństwo wątków!" ale nie ma również wyraźnego "Nie martw się o nici, których nie ma".

Nic nie robimy jawnie z wątkami w naszym kodzie Pythona, nie ma o nich żadnej wzmianki we wszystkim, co napisaliśmy.

Ale niektórzy ludzie są zdania, że ​​skoro używamy wersji threads=15, jesteśmy teraz w świecie wielowątkowym.

Czy ktoś może wyjaśnić, co się tutaj dzieje? Czy nasz kod Pythona podlega teraz wielu wątkom wykonywania przez te same dane, na których wcześniej nie było, czy też nie?

Odpowiedz

6

Tak oczywiście używasz wielowątkowych aplikacji i będzie to powodować problemy, jeśli nie dbać o globalnych, klasa atrybutów itp

Jeśli trzeba zachować coś globalnie, przechowywać go w pamięć lokalna wątku.

Oto cytat z modwsgi doc, Building_A_Portable_Application

3. Wniosek musi być ponownie zgłoszony lub po prostu być w stanie być wywołanym jednocześnie przez wiele wątków w tym samym czasie. Dane, które musi istnieć przez całe życie żądania, muszą być przechowywane jako dane na podstawie stosu, wątkować dane lokalne lub buforowane w środowisku WSGI . Zmiennych globalnych w obrębie rzeczywistego modułu aplikacji nie można użyć do tego celu.

Sądzę, że zostaliście wystarczająco ostrzeżeni.

0

Interpreter pytonów nie jest bezpieczny dla wątków, szczególnie z powodu zliczania odwołań, więc wątki nie mogą jednocześnie uzyskać dostępu do obiektów Pythona w tej samej przestrzeni procesu. Nie ma możliwości skonfigurowania mod_wsgi do obejścia tego, przypadkowo lub celowo, ponieważ interpreter jest chroniony przez GIL (globalna blokada interpretera). Dlatego nie musisz martwić się o szczególnie trudne problemy z bezpieczeństwem wątków, które wiążą się z ryzykiem równoczesnych wątków uzyskujących dostęp do tych samych obiektów pamięci (blokowanie pamięci itp.).

Niektóre serwery internetowe, takie jak gunicorn z gevent backer, będą miały jednocześnie wiele wątków w pamięci, więc żaden proces nie musi być blokowany na I/O (dostęp do bazy danych, dostęp do sieci itp.). Może tak być również w przypadku mod_wsgi. Jest to jednak zaimplementowane w taki sposób, że nie musisz martwić się o to w swoim kodzie aplikacji - jeśli twoja aplikacja jest bezpieczna do użycia przy wieloprocesowym przetwarzaniu, powinna być również bezpieczna w użyciu w tego rodzaju ograniczonych, nie współbieżnych wątkach Model.

Oczywiście nie można używać zmiennych globalnych ani dynamicznie edytować części aplikacji w trakcie działania, ale jeśli robisz coś takiego w Django, napotkasz problemy jeszcze zanim będziesz musiał się martwić gwintowaniem. Django i inne frameworki internetowe są zaprojektowane tak, aby dane były przekazywane jako żądanie i jako odpowiedź, bez martwienia się o bezpieczeństwo wątków/procesów w tym modelu.

Musisz martwić się o współbieżny dostęp do magazynów danych (szczególnie wpisy bazy danych), jak w przypadku każdej aplikacji internetowej. Kod defensywnie, jeśli chodzi o dostęp do bazy danych.

+1

Przepraszam, ale stwierdzenie, że twoja wypowiedź jest bardzo mylące. Interpreter Pythona sam w sobie jest bezpieczny dla wątków, gdyby tak nie było, rozbijałby się w każdym miejscu. Wewnętrzny stan interpretera Pythona i zarządzanie licznikami referencyjnymi jest mediowany przez GIL, jak mówisz, i zapewnia bezpieczne korzystanie z interpretera Pythona z wieloma wątkami. Tak zły sposób wyjaśnienia tego. Również gunicorn z geventem nie ma wielu wątków. Podczas korzystania z geventu są one technicznie rzecz biorąc nie wątkami, ale sprawiają, że wyglądają jak wątki. –

+1

Kwestia kodu aplikacji na poziomie wątku jest inna, ale nie należy mylić tego z tym, czy interpreter Pythona jest bezpieczny dla wątków. –

+0

Przy pierwszym zliczaniu, przypuszczam, że to prawda, chociaż nie jestem pewien, czy jest mniej dokładne opisywanie interpretera python jako nie wątku bezpiecznego dla operacji pamięciowych na obiektach Pythona w tym samym czasie, niż wyjaśnienie, że jest bezpieczny dla wątków. ponieważ GIL uniemożliwia wykonywanie powyższych czynności. Po drugim liczeniu zgadzam się; gevent używa "zielonych nici", które technicznie nie są nitkami - powinienem to wyjaśnić. –

1

Myślę, że odpowiedź Andrew jest trochę myląca. Fakt, że CPython (zauważ, że istnieją inne implementacje Pythona, takie jak Jython i PyPy) ma GIL, nie oznacza, że ​​nie musisz się martwić o to, że twój kod jest bezpieczny dla wątków! Ze względu na GIL, żaden z dwóch wątków w jednym procesie nie może być aktywny w tym samym czasie. Ale równoległość jest symulowana poprzez okresowe przełączanie między wątkami. I taka zmiana kontekstu może się zdarzyć w dowolnym czasie podczas wykonywania twojego programu. Na przykład, jeśli masz moduł foo zawierający "globalną" zmienną x, to następująca metoda może wyprowadzić wszystko z 2, 3, 4, ..., w zależności od liczby wątków wykonujących tę samą metodę:

def bar(): 
    foo.x = 1 
    # a context switch might happen here! 
    foo.x = foo.x + 1 
    # or here! 
    print(foo.x) 

Właściwie można skonfigurować mod_wsgi do używania max. 1 wątek. A potem nie musisz się martwić o bezpieczeństwo nici. Ale poprawność twojego programu zależy od konfiguracji serwera WWW, co jest bardzo niepożądaną sytuacją.

Powiązane problemy