Ctrlc完了するのに長い時間がかかるプロセスを停止しようとすると、シェルを2回打ちました。
^C
二度繰り返されたが、その過程は続いた。
Ctrlcいつものようにプロセスを終了したらどうでしょうか?
答え1
プロセスは以下を選択できます。
- 押されたときに通常送信されるSIGINT信号を無視するかCtrl-C(シェルのように
trap '' INT
)、独自のハンドラが終了しないことを決定するか(または時間内に終了しません)。 - SIGINTをフォアグラウンドジョブとして送信した文字が、他の文字(
stty int '^K'
シェルのwithなど)であることを端末装置に通知します。 stty -isig
(シェルと同様に)信号を送信しないように端末装置に指示します。
または、中断できないシステムコールなど、中断することはできません。
Linux(比較的新しいカーネルを含む)では、プロセスが無視しているかどうかを確認できます。扱うSIGINTによる出力の表示
$ kill -l INT
2
$ grep Sig "/proc/$pid/status"
SigQ: 0/63858
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000002
SigCgt: 0000000000000000
SIGINTは2です。上記のSigIgnの2番目のビットは1で、SIGINTが無視されることを示します。
これにより、これを自動化できます。
$ SIG=$(kill -l INT) perl -lane 'print $1 if $F[0] =~ /^Sig(...):/ &&
$F[1] & (1<<($ENV{SIG}-1))' < "/proc/$pid/status"
Ign
intr
現在の文字が何であるか、isig
特定の端末で有効になっているかどうかを確認するには、次の手順を実行します。
$ stty -a < /dev/pts/0
[...] intr = ^C [...] isig
(上記の文字はintr
(通常)^C
押すとターミナル(エミュレータ)から送信され、入力信号は無効になりません。CTRL-C
$ stty -a < /dev/pts/1
[...] intr = ^K [...] -isig
(intr
文字は無効になっています^K
)。isig
/dev/pts/1
完全性を期すためにプロセスがSIGINTの受信を停止する他の2つの方法がありますが、一般的に見ることができる方法ではありません。
上記ではCtrl+C、SIGINT信号はプロセス内のすべてのプロセスに送信されます。端末のフォアグラウンドプロセスグループ。通常、シェルはプロセスをプロセスグループ(シェルにマップ)に配置します。働く) そして、最終デバイスにどれがあるかを教えてくれます。展望一つ。
これで、プロセスは次のことができます。
対応するプロセスグループを離れます。別のプロセスグループ(現在のプロセスグループを除くすべてのプロセスグループ)に移動する場合展望Ctrl-C1)これで、SIGINT(またはSIGTSTP、SIGQUITなどの他のキーボード関連信号)を受信しなくなります。ただし、端末デバイスから読み取り(および端末デバイスの設定に応じて書き込み)を試みると(バックグラウンドプロセスのように)中断される可能性があります。
たとえば、
perl -MPOSIX -e 'setpgid(0,getppid) or die "$!"; sleep 10'
中断できませんCtrl-C。上記は、
perl
親プロセスIDと同じIDを持つプロセスグループに参加しようとします。一般に、そのIDを持つプロセスグループが存在するという保証はありません。ただし、ここでperl
コマンドが対話型シェルのプロンプトで単独で実行されると、ppidはシェルのプロセスになり、シェルは通常独自のプロセスグループから始まります。コマンドがまだプロセスグループリーダー(前景プロセスグループのリーダー)でない場合は、新しいプロセスグループを起動して同じ効果を得ます。
例えば、シェルによると、
$ ps -j >&2 | perl -MPOSIX -e 'setpgid(0,0) or die "$!"; sleep 10' PID PGID SID TTY TIME CMD 21435 21435 21435 pts/12 00:00:00 zsh 21441 21441 21435 pts/12 00:00:00 ps 21442 21441 21435 pts/12 00:00:00 perl
同じ効果があるでしょう。フォアグラウンドプロセスグループから始まりますが、ほとんどのシェルは
ps
そのグループのリーダーになるので(上記の出力からわかるように、pgidはpidです)、独自のプロセスグループを起動できます。perl
ps
ps
ps
perl
ps
perl
あるいは、フォアグラウンドプロセスグループを変更することもできます。デフォルトでは、ttyデバイスにSIGINTを別のプロセスグループに送信するように指示します。Ctrl+C
perl -MPOSIX -e 'tcsetpgrp(0,getppid) or die$!; sleep 5'
そこで
perl
同じプロセスグループに滞在し、フォアグラウンドプロセスグループのIDが親プロセスIDと同じであることを端末デバイスに通知します(上記の注意事項を参照)。