Czy linux zabija procesy w tle, jeśli zamkniemy terminal, z którego został uruchomiony?
Mam wbudowany system, na którym robię telnet
, a następnie uruchamiam aplikację w tle:
./app_name &
Teraz, jeśli zamknę mój terminal i zrobię telnet
z innego terminala i jeśli sprawdzę, to widzę, że ten proces nadal działa.
Aby to sprawdzić napisałem mały program:
#include<stdio.h>
main()
{
while(1);
}
Uruchomiłem ten program na moim lokalnym komputerze z Linuksem w tle i zamknąłem terminal.
Teraz, kiedy sprawdzałem ten proces z innego terminala, okazało się, że ten proces był także zabity.
Moje pytanie brzmi:
- dlaczego nieokreślone zachowanie dla tego samego typu procesu? Od czego to zależy?
- czy to zależy od wersji Linuksa?
4 answers
Kto powinien zabijać Jobsa?
Zwykle zadania pierwszoplanowe i w tle są zabijane przez SIGHUP
wysyłane przez jądro lub powłokę w różnych okolicznościach.
Kiedy kernel wysyła SIGHUP
?
Kernel wysyła SIGHUP
do proces kontrolny:
- W przeciwieństwie do innych terminali terminalowych, terminale terminalowe mogą być używane w terminalach terminalowych.]}
- dla pseudoterminal (pty): kiedy ostatni deskryptor strona wzorcowa pty jest zamknięta, np. po zamknięciu okna terminala.
jądro wysyła SIGHUP
do innych grup procesów:
- do grupy procesów pierwszoplanowych , gdy kontrolowanie procesu kończy się;
- to grupa procesów osieroconych, kiedy zostaje osierocony i zatrzymuje członków.
Kontrolowanie procesu jest liderem sesji, który ustanowił połączenie z kontroluję terminal.
Zazwyczaj procesem kontrolującym jest twoja powłoka. Podsumowując:
- Jądro wysyła
- jądro wysyła
SIGHUP
do grupy procesów pierwszoplanowych, gdy powłoka zakończy działanie; - kernel wysyła
SIGHUP
do osieroconej grupy procesów, jeśli zawiera zatrzymane procesy.
SIGHUP
do powłoki, gdy prawdziwe lub pseudoterminalne są odłączone / zamknięte;
Zauważ, że jądro nie wysyła SIGHUP
do grupy procesów w tle, jeśli nie zawiera zatrzymanych procesów.
Kiedy bash
wyśle SIGHUP
?
Bash wysyła SIGHUP
do wszystkie zadania (pierwszy plan i tło):
- W przeciwieństwie do innych programów, które nie są w pełni kompatybilne z komputerem, nie są w pełni kompatybilne z komputerem.]}
- gdy zakończy działanie, jest to interaktywna powłoka logowania i ustawiona jest opcja
huponexit
(i kontrola pracy jest włączona podczas kompilacji).
Zobacz więcej szczegóły tutaj .
Uwagi:
-
bash
nie wysyłaSIGHUP
do zadań usuniętych z listy zadań za pomocądisown
; - procesy zaczęły używać
nohup
ignorujSIGHUP
.
Więcej szczegółów tutaj .
A co z innymi muszlami?
Zazwyczaj muszle rozmnażają się SIGHUP
. Generowanie SIGHUP
przy normalnym wyjściu jest mniej powszechne.
Telnet lub SSH
W ramach telnet lub SSH należy dzieje się, gdy połączenie jest zamknięte (np. gdy zamykasz telnet
okno na komputerze):
- Klient zostaje zabity; Serwer wykrywa, że połączenie z Klientem jest zamknięte;]}
- serwer zamyka główną stronę pty;
- kernel wykrywa, że master pty jest zamknięty i wysyła
SIGHUP
dobash
; -
bash
odbieraSIGHUP
, wysyłaSIGHUP
do wszystkich zadań i kończy pracę; - każde zadanie otrzymuje
SIGHUP
i kończy się.
Problem
Mogę odtworzyć Twoje problem z użyciem bash
i telnetd
z busybox
lub dropbear
serwera SSH: czasami , zadanie w tle nie odbiera SIGHUP
(i nie kończy się) po zamknięciu połączenia z klientem.
telnetd
lubdropbear
) zamyka główną stronę pty, to wygląda na to, że stan race ( występuje, gdy serwer (telnetd
lub dropbear
) zamyka główną stronę pty:
-
W zależności od tego, która z nich jest wykonywana, zadania są wykonywane w tle, a następnie wykonywane w tle.]}
- ale czasami,
bash
wykrywaEOF
Po stronie niewolnika pty przed obsługąSIGHUP
.
Gdy bash
wykryje EOF
, domyślnie kończy się natychmiast bez wysyłania SIGHUP
. A praca w tle nadal działa!
Rozwiązanie
Możliwe jest skonfigurowanie bash
, Aby wysłać SIGHUP
przy normalnym wyjściu (w tym EOF
) również:
-
Upewnij się, że
bash
jest uruchomiony jako powłoka logowania . Nahuponexit
działa tylko dla powłok logowania, AFAIK.Powłoka logowania jest włączona przez
-l
opcja lub myślnik wiodący wargv[0]
. Możesz skonfigurowaćtelnetd
, aby uruchamiać/bin/bash -l
lub lepiej/bin/login
, które wywołuje/bin/sh
w trybie powłoki logowania.Np.:
telnetd -l /bin/login
-
Włącz opcję
huponexit
.Np.:
shopt -s huponexit
Wpisz to w
bash
sesji za każdym razem lub Dodaj do.bashrc
lub/etc/profile
.
Dlaczego dochodzi do wyścigu?
bash
odblokowuje sygnały tylko wtedy, gdy jest bezpieczny, i blokuje je, gdy jakiś kod sekcja nie może być bezpiecznie przerwana przez obsługę sygnału.
Takie sekcje krytycznewywołują punkty przerwania od czasu do czasu i jeśli sygnał jest odbierany podczas wykonywania sekcji krytycznej, jej obsługa jest opóźniona do następnego punktu przerwania lub zakończenia sekcji krytycznej.
Możesz zacząć kopać od quit.h
w kodzie źródłowym.
Tak więc, wydaje się, że w naszym przypadku bash
czasami otrzymuje SIGHUP
, gdy jest w sekcja krytyczna. SIGHUP
wykonanie obsługi jest opóźnione, a bash
odczytuje EOF
i kończyprzed opuszczeniem sekcji krytycznej lub wywołaniem następnego punktu przerwania.
Odniesienie
- Sekcja"Kontrola pracy" w oficjalnym podręczniku Glibc.
- Rozdział 34 "grupy procesów, sesje i kontrola Zadań" książki "interfejs programowania Linuksa".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:08
Aby w pełni zrozumieć, co się dzieje, musisz trochę wejść w unix
wewnętrzne.
Gdy uruchamiasz takie polecenie
./app_name &
app_name
jest wysyłany do grupy procesów w tle. Możesz sprawdzić o unix
grupy procesów tutaj
Kiedy zamykasz bash
normalnym wyjściem uruchamia SIGHUP
sygnał zawieszenia do wszystkich swoich zadań. Niektóre informacje na temat unix
kontroli pracy jest tutaj .
Aby zachować swoją aplikację uruchamianie po wyjściu bash
aplikacja musi być odporna na sygnał zawieszenia za pomocą narzędzia nohup
.
Nohup-uruchom polecenie odporne na rozłączenia, z wyjściem na nie-tty
I w końcu tak musisz to zrobić.
nohup app_name & 2> /dev/null;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-25 11:28:58
Kiedy zamykasz terminal, shell wysyła SIGHUP
do wszystkich procesów w tle – i to je zabija. Można to stłumić na kilka sposobów, przede wszystkim:
Nohup
Kiedy uruchamiasz program z nohup
to łapie SIGHUP
i przekierowuje wyjście programu.
$ nohup app &
Disown
disown
mówi shellowi, aby nie wysyłał SIGHUP
$ app &
$ disown
Czy to zależy od wersji Linuksa?
To zależy od twojej skorupy. Powyższe dotyczy co najmniej bash.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-09 15:25:18
AFAIK w obu przypadkach proces powinien zostać zabity. Aby tego uniknąć, musisz wydać nohup w następujący sposób:
> nohup ./my_app &
W ten sposób proces będzie kontynuowany. Prawdopodobnie część telnet jest spowodowana błędem podobnym do tego:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-11 07:23:46