Wyjaśnienie wątków demona

237

W dokumentacji Pythona napisano:

Wątek można oznaczyć jako „wątek demona”. Znaczenie tej flagi polega na tym, że cały program Python kończy działanie, gdy pozostaną tylko wątki demona. Wartość początkowa jest dziedziczona z wątku tworzącego.

Czy ktoś ma jaśniejsze wyjaśnienie tego, co to oznacza, lub praktyczny przykład pokazujący, gdzie należy ustawić wątki daemonic?

Wyjaśnij to dla mnie: więc jedyną sytuacją, w której nie ustawiłeś wątków daemonic, jest sytuacja, w której chcesz, aby kontynuowały działanie po wyjściu z głównego wątku?

Corey Goldberg
źródło

Odpowiedzi:

448

Niektóre wątki wykonują zadania w tle, takie jak wysyłanie pakietów podtrzymujących lub okresowe usuwanie śmieci lub cokolwiek innego. Są one użyteczne tylko wtedy, gdy główny program jest uruchomiony, i można je zabić, gdy inne wątki niebędące demonami zakończą działanie.

Bez wątków demona będziesz musiał ich śledzić i powiedzieć im, aby zakończyli pracę, zanim program całkowicie się zakończy. Ustawiając je jako wątki demona, możesz pozwolić im działać i zapomnieć o nich, a gdy program zakończy działanie, wszelkie wątki demonów są automatycznie zabijane.

Chris Jester-Young
źródło
1
Więc jeśli mam wątek potomny, który wykonuje operację zapisu pliku, która jest ustawiona na non-deamon, czy to oznacza, że ​​muszę jawnie zakończyć działanie?
Ciasto piekarz
8
@san Co robi wątek autora po zakończeniu pisania? Czy to po prostu powraca? Jeśli tak, to wystarczy. Wątki demonów są zwykle przeznaczone dla rzeczy, które działają w pętli i same nie wychodzą.
Chris Jester-Young
Nic nie robi, ani nie zwraca, a jego jedynym celem jest operacja zapisu plików
Ciasto piekarz
2
@ san Jeśli spadnie z dołu funkcji wątku, powróci niejawnie.
Chris Jester-Young
W Nonetakim przypadku zwraca , ale nie ma znaczenia, wartość zwracana nie jest używana.
Chris Jester-Young
30

Załóżmy, że tworzysz rodzaj widżetu na pulpicie nawigacyjnym. W ramach tego chcesz wyświetlać liczbę nieprzeczytanych wiadomości w skrzynce e-mail. Więc tworzysz mały wątek, który:

  1. Połącz się z serwerem poczty i zapytaj, ile masz nieprzeczytanych wiadomości.
  2. Sygnalizuj GUI zaktualizowaną liczbą.
  3. Śpij przez chwilę.

Gdy widget się uruchomi, utworzy ten wątek, wyznaczy go jako demona i uruchomi. Ponieważ jest to demon, nie musisz o tym myśleć; po wyjściu widgetu wątek zatrzyma się automatycznie.

John Fouhy
źródło
18

Inne plakaty podały kilka przykładów sytuacji, w których można użyć wątków demona. Jednak zalecam, aby nigdy ich nie używać.

Nie dlatego, że nie są użyteczne, ale dlatego, że przy ich użyciu mogą wystąpić złe skutki uboczne. Wątki demona mogą nadal być wykonywane po tym, jak środowisko wykonawcze Python zacznie niszczyć rzeczy w głównym wątku, powodując dość dziwne wyjątki.

Więcej informacji tutaj:

https://joeshaw.org/python-daemon-threads-consanted-harmful/

https://mail.python.org/pipermail/python-list/2005-Feb February/343697.html

Ściśle mówiąc, nigdy ich nie potrzebujesz, w niektórych przypadkach po prostu ułatwia wdrożenie.

Joe Shaw
źródło
Nadal ten problem z python 3? W dokumentacji nie ma jasnych informacji dotyczących tych „dziwacznych wyjątków”.
kheraud
5
Z postu na blogu Joe: „Aktualizacja czerwca 2015 r .: To jest błąd Pythona 1856. Został on naprawiony w Python 3.2.1 i 3.3, ale poprawka nigdy nie została przeniesiona do wersji 2.x. (Próba przeniesienia do gałęzi 2.7 spowodowała kolejny błąd i zostało porzucone.) Wątki demona mogą być poprawne w Pythonie> = 3.2.1, ale zdecydowanie nie są we wcześniejszych wersjach. "
clacke
Chciałbym się tutaj podzielić moim doświadczeniem: wielokrotnie miałem funkcję spawnowaną jako Wątek. Wewnątrz miałem instancję Pythona loggingi spodziewałem się, że po zakończeniu wątku wszystkie obiekty (deskryptory plików dla każdego wątku / funkcji) zostaną zniszczone. Pod koniec mojego programu widziałem wiele takich wyników IOError: [Errno 24] Too many open files:. Z lsof -p pid_of_programodkryłem, że FDS były otwarte, nawet trudna jest Temat / Funkcje zakończeniu pracy. Obejście? Usuwanie modułu obsługi dziennika na końcu funkcji. daemonicNici więc nie są godne zaufania ...
ivanleoncz
17

Być może jest to prostszy sposób: po powrocie main proces nie zakończy się, jeśli nadal działają wątki niebędące demonami.

Mała rada: czyste zamknięcie jest łatwe do popełnienia błędu, gdy w grę wchodzą wątki i synchronizacja - jeśli możesz tego uniknąć, zrób to. W miarę możliwości używaj wątków demona.

Jonathan
źródło
13

Chris wyjaśnił już, czym są wątki demonów, więc porozmawiajmy o praktycznym użyciu. Wiele implementacji pul wątków używa wątków demonów dla pracowników zadań. Pracownicy to wątki, które wykonują zadania z kolejki zadań.

Pracownik musi bez końca czekać na zadania w kolejce zadań, ponieważ nie wie, kiedy pojawi się nowe zadanie. Wątek, który przypisuje zadania (powiedz główny wątek) wie tylko, kiedy zadania się skończyły. Główny wątek czeka w kolejce zadań na opróżnienie, a następnie kończy działanie. Jeśli pracownicy są wątkami użytkownika, tzn. Nie są demonami, program się nie zakończy. Będzie czekał na tych nieskończenie działających pracowników, nawet jeśli pracownicy nie robią nic pożytecznego. Oznacz wątki demonów pracowników, a wątek główny zajmie się ich zabiciem, gdy tylko zakończy wykonywanie zadań.

Amit
źródło
4
Uważaj na to! Jeśli program prześle ważne zadanie (np. Zaktualizuje jakiś plik „w tle”) do kolejki zadań demona, istnieje ryzyko, że program może zakończyć się przed wykonaniem zadania lub, co gorsza, w trakcie aktualizacji tego pliku.
Solomon Slow
10

Cytując Chrisa: „... kiedy twój program się kończy, wszelkie wątki demonów są automatycznie zabijane.”. Myślę, że to podsumowuje. Powinieneś być ostrożny, gdy ich używasz, ponieważ nagle kończą się, gdy główny program wykonuje się do końca.

Gitara basowa
źródło
4

Gdy drugi wątek nie jest demonem, główny główny wątek aplikacji nie może wyjść, ponieważ jego kryteria wyjścia są powiązane z wyjściem również wątków innych niż demony. Wątki nie mogą być przymusowo zabijane w pythonie, dlatego Twoja aplikacja będzie musiała naprawdę czekać na zakończenie wątków nie-demona. Jeśli takie zachowanie nie jest tym, czego chcesz, ustaw drugi wątek jako demon, aby nie powstrzymywał Twojej aplikacji przed zamknięciem.

trueadjustr
źródło