O envio de SIGINT para processar grupos às vezes é ignorado

4

Eu inicio um grupo de processos do bash. Então eu envio SIGINT para todo o processo grupo. Às vezes o SIGINT mata os processos, às vezes não. Porque SIGINT às vezes é ignorado?

Eu vejo um comportamento diferente dependendo se o grupo de processos é iniciado em o fundo ou não, no aninhamento de shells bash e no Mac / Linux operacional sistema. Eu realmente aprecio se alguém puder lançar alguma luz sobre isso.

Nos exemplos a seguir, eu uso este executável python chamado sleep_in_pgrp.py

#!/usr/bin/env python2.7
import os;
import subprocess
os.setpgrp();
subprocess.check_call(["sleep","10000"]);

Cria um grupo de processos e começa a dormir. Os fenômenos observados não devem estar relacionado ao python. Eu uso python apenas porque o bash não tem um setpgrp comando ou incorporado. Update : Aparentemente, pode-se também executar um shell para criar um novo grupo de processos

1) Inicie o grupo de processos em segundo plano e aguarde o líder. SIGINT é ignorado.

Execute o seguinte comando:

$ bash -c '  { sleep_in_pgrp.py; } & wait $!  '

O Bash inicia o python em segundo plano e espera nele. Em outro terminal:

$ ps -Heo pid,ppid,tpgid,pgid,sid,user,args
   PID   PPID  TPGID   PGID    SID     COMMAND
  2507   1574   2963   2507   2507     -bash
  2963   2507   2963   2963   2507       bash -c   { sleep_in_pgrp.py; } & wait $!
  2964   2963   2963   2963   2507         bash -c   { sleep_in_pgrp.py; } & wait $!
  2965   2964   2963   2965   2507           python2.7 ./sleep_in_pgrp.py
  2966   2965   2963   2965   2507             sleep 10000

SIGINT o grupo de processos do python não elimina nenhum processo . Qual pode ser a razão ?

$ sudo kill -s SIGINT -- -2965

2) Inicie o grupo de processos em primeiro plano. SIGINT funciona.

Se eu remover o & wait $! , o SIGINT eliminará o grupo de processos conforme o esperado. Eu não sei porque, mas não estou surpreso SIGINT matou os processos neste caso.

$ bash -c '  { sleep_in_pgrp.py; }  '

Em outro terminal:

$ ps -Heo pid,ppid,tpgid,pgid,sid,user,args
   PID   PPID  TPGID   PGID    SID     COMMAND
  2507   1574   3352   2507   2507     -bash
  3352   2507   3352   3352   2507       bash -c   { sleep_in_pgrp.py; }
  3353   3352   3352   3353   2507         python2.7 ./sleep_in_pgrp.py
  3354   3353   3352   3353   2507           sleep 10000

SIGINT mata o grupo de processos.

$ sudo kill -s SIGINT -- -3353

3) Removendo o subshell durante a execução do python em segundo plano. SIGINT funciona.

Fiquei muito surpreso que o aninhamento da concha afeta o comportamento aqui. Não consigo pensar em nenhuma explicação do porquê.

Eu removi o bash -c no início:

$ { sleep_in_pgrp.py; } & wait $!

Em outro terminal:

$ ps -Heo pid,ppid,tpgid,pgid,sid,user,args
   PID   PPID  TPGID   PGID    SID     COMMAND
  2507   1574   2507   2507   2507     -bash
  3488   2507   2507   3488   2507       -bash
  3489   3488   2507   3489   2507         python2.7 ./sleep_in_pgrp.py
  3490   3489   2507   3489   2507           sleep 10000

SIGINT mata o grupo de processos.

$ sudo kill -s SIGINT -- -2507

4) Executando o primeiro comando no Mac: o SIGINT funciona.

Os primeiros 2 comandos foram executados em uma VM CentOs7.

$ uname -a
Linux ip-10-229-193-124 3.10.0-693.5.2.el7.x86_64 #1 SMP Fri Oct 13 10:46:25 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux

Eu agora executo o primeiro comando com python em segundo plano em um subshell no mac.

$ uname -a
Darwin mbp-005063 15.6.0 Darwin Kernel Version 15.6.0: Sun Jun  4 21:43:07 PDT 2017; root:xnu-3248.70.3~1/RELEASE_X86_64 x86_64

No Mac:

$ bash -c '  { sleep_in_pgrp.py; } & wait $!  '

Em outro terminal:

$   PID  PPID TPGID  PGID   SESS COMMAND
18741 40096 18741 18741      0 bash -c   { sleep_in_pgrp.py; } & wait $!
18742 18741 18741 18741      0 bash -c   { sleep_in_pgrp.py; } & wait $!
18743 18742 18741 18743      0 /usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python ./sleep_in_pgrp.py
18744 18743 18741 18743      0 sleep 10000
40094  2423 18741 40094      0 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server /usr/bin/login -fpl hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
40095 40094 18741 40095      0 /usr/bin/login -fpl hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
40096 40095 18741 40096      0 -bash
-+= 00001 root /sbin/launchd
 \-+= 02423 hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2
   \-+= 40094 hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --server /usr/bin/login -fpl hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
     \-+= 40095 root /usr/bin/login -fpl hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
       \-+= 40096 hbaba -bash
         \-+= 18741 hbaba bash -c   { sleep_in_pgrp.py; } & wait $!
           \-+- 18742 hbaba bash -c   { sleep_in_pgrp.py; } & wait $!
             \-+= 18743 hbaba /usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python ./sleep_in_pgrp.py
               \--- 18744 hbaba sleep 10000

E neste caso, o SIGINT também mata o grupo de processos

$ sudo kill -s INT -18743

A versão do Bash no CentOs7 é

$ echo $BASH_VERSION
4.2.46(2)-release

No Mac, a versão bash é

$ echo $BASH_VERSION
4.4.12(1)-release

Esta resposta explica como CLTRL-C envia SIGINT para o grupo de processos. É o que estou tentando fazer aqui enviando SIGINT para um grupo de processos. Esta resposta menciona que não trabalhos interativos requerem um manipulador SIGINT. Não tenho certeza se explica o comportamento variável que vejo. Eu também estou querendo saber se esperar em um fundo O processo afeta o processamento do SIGINT por esse processo.

    
por Hakan Baba 29.10.2017 / 09:03

1 resposta

0

É tão possível que este processo capture o sinal SIGINT para usar com outra função.

O processo só está morto se o sinal recebido for desconhecido para ele. Mas, se o processo definir uma função ligada a este sinal, ele não ficará inoperante, a menos que a função ligada a este sinal termine o programa.

Por exemplo, um programa simplesmente C:

 #include <signal.h>

 int sigreceived = 0;

 void mysignal();

 int main(){
    signal(2, mysignal); //SIGINT corresponds to 2 signal

    while(1);
    return 0;
  }

 void mysignal(){
  sigreceived=1;
 }

Neste programa, o sinal 2 é capturado para chamar a função mysignal que, em vez de matar o processo, simplesmente altera o valor de uma variável

Então, esse processo não mata com SIGINT

    
por 20.02.2018 / 11:24