Фоновые процессы получают SIGHUP, выходя из системы?

Вы посмотрели на свои журналы производительности для наблюдения, каково узкое место? Я предложил бы включить контроль диска ввод-вывод, сети, загрузка процессора и подкачка страниц памяти, чтобы запуститься с и видеть, привязывает ли один из них. Это затем дало бы Вам признак того, что необходимо обновить для увеличения производительности.

21
задан 13 April 2017 в 15:14
4 ответа

Ответ найден.

Для Bash это зависит от huponexit опция оболочки, которая может быть просмотрена и/или устанавливает использование встроенного shopt команда.

Похож на это, опции прочь по умолчанию, по крайней мере, в основанных на Redhat системах.

Больше информации о странице справочника Bash:

Оболочка выходит по умолчанию по получении SIGHUP. Перед выходом интерактивная оболочка снова посылает SIGHUP всем заданиям, работая или остановилась. Остановленные задания отправляются SIGCONT, чтобы гарантировать, чтобы они получили SIGHUP. Чтобы препятствовать тому, чтобы оболочка отправила сигнал в конкретное задание, это должно быть удалено из таблицы заданий с отрицанием встроенного (см. SHELL ВСТРОЕННЫЕ КОМАНДЫ ниже), или отмеченный для не получения использования SIGHUP отрицают-h.

Если опция оболочки huponexit была установлена с shopt, удар отправляет SIGHUP во все задания, когда интерактивная оболочка входа в систему выходит.

26
ответ дан 2 December 2019 в 20:05
  • 1
    Проверенный. Когда я выполнил " exit" " logout" или CTL-D дочерний proc (задание) не получил бы регистрацию (и корневой и reg пользователь). Однако, когда я сделал " уничтожьте - ПОНУКАЮТ $$ " для уничтожения текущего экземпляра удара дочерние процессы DID получают регистрацию. Я затем установил huponexit, и дочерний процесс действительно получал SIGHUP на выход. –  CarpeNoctem 26 February 2010 в 16:19

Это будет отправлено SIGHUP в моих тестах:

Shell1:

[kbrandt@kbrandt-opadmin: ~] ssh localhost
[kbrandt@kbrandt-opadmin: ~] perl -e sleep & 
[1] 1121
[kbrandt@kbrandt-opadmin: ~] ps
  PID TTY          TIME CMD
 1034 pts/46   00:00:00 zsh
 1121 pts/46   00:00:00 perl
 1123 pts/46   00:00:00 ps

Shell2:

strace -e trace=signal -p1121

Shell1 снова:

[kbrandt@kbrandt-opadmin: ~] exit
zsh: you have running jobs.
[kbrandt@kbrandt-opadmin: ~] exit
zsh: warning: 1 jobs SIGHUPed
Connection to localhost closed.

Shell2 снова:

strace -e trace=signal -p1121
Process 1121 attached - interrupt to quit
pause()                                 = ? ERESTARTNOHAND (To be restarted)
--- SIGHUP (Hangup) @ 0 (0) ---
Process 1121 detached

Почему это все еще работает?:
Усовершенствованное Программирование в Среде Unix Stevens покрывает это под разделом 9.10: Осиротевшие Группы Процесса. Самое соответствующее раздел быть:

Так как группа процесса является осиротевшей, когда родитель завершается, POSIX.1 требует, что каждый процесс в недавно осиротевшей группе процесса, которая останавливается (поскольку наш ребенок) быть отправленным сигнал зависания (SIGHUP), сопровождаемый продолжать сигналом (SIGCONT).

Это заставляет ребенка быть продолженным после обработки сигнала зависания. Действие по умолчанию для сигнала зависания должно завершить процесс, таким образом, мы должны обеспечить обработчик сигналов для ловли сигнала. Мы поэтому ожидаем, что printf в функции sig_hup появится перед printf в функции pr_ids.

3
ответ дан 2 December 2019 в 20:05
  • 1
    Но Вы явно отправили SIGHUP в него сюда; я говорил о том, что происходит, когда Вы выходите из системы оболочки, где Вы запустили процесс. –  Massimo 26 February 2010 в 15:32
  • 2
    Те же результаты, когда я ввожу выход, хотя я получаю предупреждение о заданиях, но затем ввожу выход снова. Я протестировал это с ZSH. –  Kyle Brandt 26 February 2010 в 15:33
  • 3
    I' m использование Bash, и это, вероятно, зависит от оболочки. Но BASH должен отправлять SIGHUP в дочерние процессы, выходя из системы... –  Massimo 26 February 2010 в 15:41
  • 4
    Bash отправляет SIGCONT, по-видимому, если задание останавливается, но я подтверждаю это doesn' t отправляют что-либо, если задание не было остановлено. –  Kyle Brandt 26 February 2010 в 15:47

Я использую csh, и фоновые процессы продолжают работать вперед, когда я выхожу из системы.

0
ответ дан 2 December 2019 в 20:05

أجريت بعض الاختبارات باستخدام CentOS 7.1 و bash. لاحظ أن هذا يعني أن huponexit تم إيقاف على افتراضيًا ، وتم إيقافه لمعظم اختباراتي.

أنت بحاجة إلى nohup عندما تبدأ وظيفة في الطرفية ، لأن إذا أغلقت ذلك الطرف دون الخروج من القشرة بشكل نظيف ، فإن المحطة ترسل إشارة SIGHUP إلى الغلاف ، والتي ترسلها بعد ذلك إلى جميع الأطفال. إذا خرجت من shell بشكل نظيف - مما يعني أن المهمة يجب أن تكون بالفعل في الخلفية حتى تتمكن من كتابة خروج أو الضغط على Control-D في موجه الأوامر - لا يتم إرسال أي إشارات من أي نوع إلى وظيفة الخلفية من bash .

الاختبار:

Terminal 1

$ echo $$
16779

Terminal 2

$ strace -e signal -p16779
Process 16779 attached

(إغلاق المحطة 1 ، كما هو موضح في المحطة 2):

--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=16777, si_uid=3000090} ---
rt_sigprocmask(SIG_BLOCK, [CHLD TSTP TTIN TTOU], [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_SETMASK, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 8) = 0
rt_sigprocmask(SIG_SETMASK, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], NULL, 8) = 0
rt_sigaction(SIGHUP, {SIG_DFL, [], SA_RESTORER, 0x7f7ace3d9a00}, {0x456880, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], SA_RESTORER, 0x7f7ace3d9a00}, 8) = 0
kill(16779, SIGHUP)                     = 0
rt_sigreturn()                          = -1 EINTR (Interrupted system call)
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=16779, si_uid=3000090} ---
+++ killed by SIGHUP +++

Job doit.sh :

#!/bin/bash

imhupped() {
        echo "HUP" >> /tmp/outfile
}

trap imhupped SIGHUP

for i in $(seq 1 6); do echo out $i >> /tmp/outfile; sleep 5; done

ابدأ في الخلفية في المبنى رقم 1:

المبنى 1

$ ./doit.sh &
[1] 22954

ضعها في المبنى 2 ؛ أغلق Terminal 1 بعد حلقتين:

Terminal 2

$ strace -e signal -p22954
Process 22954 attached
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=22980, si_status=0, si_utime=0, si_stime=0} ---
rt_sigreturn()                          = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f7a5d547a00}, {0x43e4b0, [], SA_RESTORER, 0x7f7a5d547a00}, 8) = 0
...
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=21685, si_uid=3000090} ---
rt_sigreturn()                          = -1 EINTR (Interrupted system call)
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=23017, si_status=SIGHUP, si_utime=0, si_stime=0} ---
rt_sigreturn()                          = 0
...

الإخراج في Terminal 3:

Terminal 3

out 1
out 2
out 3
HUP
out 4
out 5
out 6

ومع ذلك ، إذا خرجت من bash ، فإنه يخرج ببساطة دون إرسال أي إشارة للطفل على الإطلاق. ستخرج المحطة الطرفية لأنه لم يعد لديها طفل ، ولكن بالطبع لا يوجد أحد لـ HUP لأن الغلاف الفرعي قد اختفى بالفعل. SIGINT ، SIG_BLOCK و SIG_SETMASK التي تراها أدناه ترجع إلى السكون في الغلاف.

المحطة 1

$ ./doit.sh &
26275

المحطة 2

$ strace -e signal -p26275
Process 26275 attached
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26280, si_status=0, si_utime=0, si_stime=0} ---
rt_sigreturn()                          = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f5edd3a5a00}, {0x43e4b0, [], SA_RESTORER, 0x7f5edd3a5a00}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x43e4b0, [], SA_RESTORER, 0x7f5edd3a5a00}, {SIG_DFL, [], SA_RESTORER, 0x7f5edd3a5a00}, 8) = 0


(..."exit" is typed in bash, notice no new signals sent...)


rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26303, si_status=0, si_utime=0, si_stime=0} ---
rt_sigreturn()                          = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f5edd3a5a00}, {0x43e4b0, [], SA_RESTORER, 0x7f5edd3a5a00}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x43e4b0, [], SA_RESTORER, 0x7f5edd3a5a00}, {SIG_DFL, [], SA_RESTORER, 0x7f5edd3a5a00}, 8) = 0

المحطة 3 ، المخرجات

out 1
out 2
out 3
out 4
out 5
out 6

ومن المثير للاهتمام ، أنني قمت بتعيين huponexit ليكون على shopt -s huponexit ؛ shopt (الخيار الأخير للمراجعة) ، ثم أجرى الاختبار الأخير ، ومرة ​​أخرى لم يرسل bash أي إشارة لعملية الخلفية . والأكثر شيوعًا ، كما رأينا أن bash أرسل الإشارة إلى عملية الخلفية بعد أن استقبلها من محطة أغلقت في وجهها.يبدو كما لو أن huponexit ليس له تأثير بطريقة أو بأخرى.

آمل أن يزيل هذا أي غموض أو ارتباك فيما يتعلق على الأقل بعجوبة باش ، حول متى وكيف يتم إرسال إشارة HUP. على الأقل كانت اختباراتي قابلة للتكرار تمامًا ، بالنسبة لي. سأكون مهتمًا بمعرفة ما إذا كانت هناك أي إعدادات أخرى قد تؤثر على سلوك bash.

وكالعادة ، YSMV (قد يختلف شل الخاص بك).

الملحق 1

عندما أقوم بتشغيل shell كـ exec / bin / sh ، ثم قم بتشغيل البرنامج النصي كـ / bin / sh ./doit.sh & ، ثم اخرج من الغلاف بشكل نظيف ، ولا يتم إرسال أي إشارات إلى وظيفة الخلفية ويستمر للتشغيل حتى الاكتمال.

الملحق 2

عندما أقوم بتشغيل قذيفة كـ exec / bin / csh ، قم بتشغيل البرنامج النصي كـ / bin / sh ./doit.sh & ، ثم اخرج من الغلاف بشكل نظيف ، فلن يتم إرسال أي إشارات إلى وظيفة الخلفية ويستمر العمل حتى الاكتمال.

2
ответ дан 2 December 2019 в 20:05

Теги

Похожие вопросы