Dlaczego SIGUSR1 powoduje zakończenie procesu?

20

Byłem zaskoczony tym komentarzem w innym pytaniu:

Wysłanie dd sygnału USR1 zbyt wcześnie po jego uruchomieniu (tj. W skrypcie bash, wiersz po uruchomieniu) faktycznie go zakończy

Czy ktoś może wyjaśnić, dlaczego ?

Alois Mahdal
źródło
Nie tyle odpowiedź na twoje pytanie, ale wypróbuj ten linijka: { dd if=/dev/zero of=/dev/null & }; kill -USR1 $!; jobs; sleep 1; jobsaby odtworzyć opisywany efekt.
jippie

Odpowiedzi:

38

Każdy sygnał ma „domyślne ustawienie” - co domyślnie robi proces, gdy odbiera ten sygnał. Na stronie podręcznika znajduje się tabela signal(7):

Signal     Value     Action   Comment
──────────────────────────────────────────────────────────────────────
...
SIGUSR1   30,10,16    Term    User-defined signal 1
SIGUSR2   31,12,17    Term    User-defined signal 2

SIGUSR1i SIGUSR2oba mają domyślną akcję Term- proces zostaje zakończony. ddrejestruje moduł obsługi, który przechwytuje sygnał i robi z nim coś pożytecznego, ale jeśli zbyt szybko zasygnalizujesz, nie ma czasu na zarejestrowanie tego modułu obsługi, więc zamiast tego dzieje się domyślne działanie

Michał Mrożek
źródło
1
Chciałbym dwukrotnie głosować za uświadomieniem sobie tego niejasności. Obserwowanie procesów umiera losowo po usunięciu jawnej procedury obsługi sygnału było niepokojące.
DeaconDesperado,
1
Czy jest jakiś praktyczny sposób na kontrolowanie tego stanu wyścigu zamiast spania przez rozsądny okres czasu (~ 0,5-1 sekundy)? (Mam na myśli, poza czymś niedorzecznym, jak przechwytywanie i analizowanie stracewyników w skrypcie powłoki…)
Adrian Günter
Skrypt powłoki działał dobrze. Ale nagle przestań działać z powodu prawdopodobnego !: miałem teraz hipertrednictwo. Podproces wysyłający kill -s SIGUSR1 $ PARENT_PID robi się teraz zbyt szybki ?. Wnuczek uważa, że ​​rodzic jest normalnie zakończony, ale rodzic nadal wykonuje pętlę. To dobry post. Spędziłem większość dnia próbując to rozgryźć.
Kemin Zhou