Bashでプロセスグループを起動します。その後、プロセスグループ全体に SIGINT を送信します。時々SIGINTはプロセスを終了しますが、時にはそうではありません。 SIGINTが時々無視されるのはなぜですか?
プロセスグループがバックグラウンドで起動されたか、bashシェルのネスト、Mac / Linuxオペレーティングシステムによって異なる動作が表示されます。誰もがこれについて明らかにすることができれば非常に感謝します。
次の例では、Python実行可能ファイルを使用しています。sleep_in_pgrp.py
#!/usr/bin/env python2.7
import os;
import subprocess
os.setpgrp();
subprocess.check_call(["sleep","10000"]);
プロセスグループを作成し、スリープモードを開始します。観察された現象はPythonとは関係ありません。私はbashにコマンドや組み込み機能がないので、Pythonを使用していますsetpgrp
。修正する:明らかに対話型シェルを実行して新しいプロセスグループ
1) バックグラウンドでプロセスグループを起動し、リーダーを待ちます。 SIGINT は無視されます。
次のコマンドを実行します。
$ bash -c ' { sleep_in_pgrp.py; } & wait $! '
BashはバックグラウンドでPythonを起動して待ちます。他の端末から:
$ 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'ing Pythonのプロセスグループプロセスを終了しないでください。なぜですか?
$ sudo kill -s SIGINT -- -2965
2) フォアグラウンドでプロセスグループを起動します。信号知能が機能します。
を削除すると、& wait $!
SIGINTは期待どおりにプロセスグループを終了します。理由はわかりませんが、この場合、SIGINTがプロセスを終了したという事実は驚くべきことではありません。
$ bash -c ' { sleep_in_pgrp.py; } '
他の端末から:
$ 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 はプロセスグループを終了します。
$ sudo kill -s SIGINT -- -3353
3)バックグラウンドでPythonを実行している間にサブシェルを削除します。信号知能が機能します。
シェルの入れ子がここでの動作に影響を与えるという事実に非常に驚きました。私は説明を考えることができません。
bash -c
最初に削除しました。
$ { sleep_in_pgrp.py; } & wait $!
他の端末から:
$ 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 はプロセスグループを終了します。
$ sudo kill -s SIGINT -- -2507
4)Macで最初のコマンドを実行します。 SIGINTが動作します。
最初の2つのコマンドは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
これで、Macのサブシェルで背景Pythonを使用して最初のコマンドを実行します。
$ 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
Macの場合:
$ bash -c ' { sleep_in_pgrp.py; } & wait $! '
他の端末から:
$ 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
この場合、SIGINT はプロセスグループも終了します。
$ sudo kill -s INT -18743
CentOs7のBashバージョンは次のとおりです。
$ echo $BASH_VERSION
4.2.46(2)-release
Macでは、bashのバージョン
$ echo $BASH_VERSION
4.4.12(1)-release
これ回答説明+プロセスグループにSIGINTを送信するCtrl方法。CこれがプロセスグループにSIGINTを送信し、ここでやりたいことです。これ回答非対話型タスクにはSIGINTハンドラが必要であると述べました。私が見ている他の行動を説明することは不明です。また、バックグラウンドプロセスを待つことがそのプロセスのSIGINT処理に影響を与えるかどうかを知りたいです。
ベストアンサー1
このプロセスは、他の機能で使用するためにSIGINT信号を取り込む可能性が高いです。
受信した信号が不明な場合にのみプロセスは終了します。ただし、プロセスが信号に接続されている機能を設定すると、信号に接続された機能はプログラムが完了するまで死ぬことはありません。
たとえば、単純な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;
}
このプログラムでシグナル2をキャッチすることは、mysignal関数または他のものを呼び出すことです。プロセスを終了するのではなく、変数の値を変更するだけです。
これにより、このプロセスはSIGINTによって終了しません。