Qual è la differenza tra Ctrl-C e Sigint?
-
28-10-2019 - |
Domanda
Ho debug di un programma Python che seguisce dopo aver ricevuto un KeyboardInterrupt
eccezione. Questo viene normalmente fatto premendo Ctrl+c dal guscio. Per verificare se un determinato codice di codice ha risolto il bug, ho avuto un piccolo sceneggiatura che ha inviato SIGINT
al programma in tempo casuale dopo l'avvio. Il problema che ho è che l'invio Ctrl+c sembra avere un effetto diverso sul programma rispetto all'invio del segnale SIGINT
E quindi non sta causando l'appartamento del bug, quindi mi chiedo quale sia la differenza tra le due azioni.
Il programma non prende alcuna azione per tastiera ed è solo un programma Python con alcuni thread/processi. Non installa gestori di segnale (anche se Python lo fa) e stty -a
dà intr = ^C
. Sospetto che potrebbe essere quello Ctrl+c invia SIGINT
a tutti i sub-processi/thread mentre kill -INT
Invia solo il processo primario, ma questo è per quanto riguarda i miei sospetti.
Ecco lo script shell che invia il kill -INT
.
wait
while :; do
seconds="$(python -c 'import random; print random.random()*4')"
./mandos --debug --configdir=confdir \
--statedir=statedir --no-restore --no-dbus &
pid=$!
{ sleep $seconds; kill -INT $pid; } &
fg %./mandos
status=$?
if [ $status -gt 1 ]; then
echo "Failed exit $status after $seconds seconds"
break
fi
wait
done
Soluzione
^C
invia un SIGINT
a tutti i processi nel gruppo di processo in primo piano. Per fare l'equivalente con kill
, dovresti inviare il segnale al gruppo di processo (concetto a livello di sistema operativo):
kill -SIGINT -<pid>
o al lavoro (concetto a livello di shell, la pipeline si è conclusa con &
):
kill -SIGINT %
Altri suggerimenti
Come descritto qui :
Python installa un piccolo numero di gestori di segnale per impostazione predefinita: Sigpipe viene ignorato (quindi scrivere errori su tubi e prese possono essere segnalati come normali eccezioni di Python) e Sigint viene tradotto in un'eccezione tastiera. Tutti questi possono essere annullati.
Quindi, il comportamento dovrebbe essere lo stesso tra l'invio di un sigint e a Ctrl + c.
Ma devi stare attento al KeyboardInterrupt
, se da qualche parte nel tuo codice hai un
try:
...
except: # notice the lack of exception class
pass
Questo "mangerà" l'eccezione della tastiera.