フォアグラウンドでアプリを起動し、CTRL+(次に停止)を押してZバックグラウンドにドロップします。再び動作させるためにコマンドを実行しましたbg %1
(これはJOBSPECです)。
私はそれを再実行しようとしない理由が何であるかを考えましたkill -CONT <PID>
。だから私はjobs -l
PIDを取得するために走り、CONT信号と一緒にこのpidをkillと一緒に使用しました。
しかし、ショーは再び公開されませんでした!jobs -l
CONTで終了しようとすると、実行中と報告されますが、実行中ではありません(灰色で表示されるため)。
このコマンドを使用してアプリケーションPIDを確認したps
ところ、2つの同じコマンドが異なるPID(および状態Tl
)を持っていることがわかりました。
その後、同じものを使って調べたところ、pstree
どちらも親プロセスに属することがわかりました。jobs -l
バックグラウンドに配置されたプロセスは他のプログラムを起動しているように見えるため、親プロセスはリストされているプロセスとは異なります。他のプログラムが子プロセスを生成しているようです。
私が注目した内容を要約すると、次のようになります。
kill
プログラムを実行するには、親プロセスにCONTを送信します。親プロセスPIDが報告されたものとは異なります
jobs -l
。つまり、CONT信号を送信しようとしているプロセスがjobs -l
。CONT を親プロセスに送信すると、同じシグナルは子プロセスに適用されません。
bg
プロセスを実行状態に戻し、すべての子プロセスの親プロセスにCONT信号を送信するには、このコマンドを使用します。
私の結論は正しいですか?その場合、このコマンドを使用すると、bg
各関連プロセスにCONTを送信する時間が節約されます。これは正しいですか?
編集する私はコマンドラインから呼び出してバックグラウンドに配置する主なアプリケーションですgit difftool
。私が言う他のアプリケーションはそれ自身で新しいサブキーを生成し、meld
それをgitの比較ツールとして設定しました。
答え1
まず、jobs -l
記載されているプロセスはありませんが、プロセスグループ(別名日)。各プロセスグループには、プロセスID(pid)が対応するプロセスグループID(pgid)と同じプロセスリーダーがあります。
リーダーだけでなく、プロセスグループ内のすべてのプロセスにシグナルを送信するには、kill
pgidに負の数を使用して呼び出す必要があります。 Kill(2) マンページではこれについて説明します。
pidが-1未満の場合、IDが-pidのプロセスグループ内のすべてのプロセスにsigが送信されます。
シェルでも同じ効果があります。
$ sh -c 'while echo -n 1; do sleep 1; done'
111^Z
[1]+ Stopped sh -c 'while echo -n 1; do sleep 1; done'
$ jobs -l
[1]+ 11046 Stopped sh -c 'while echo -n 1; do sleep 1; done'
$ kill -CONT 11046
<nothing>
$ kill -CONT -11046
$ 11111111...
今結論を下してください。
プログラムを実行するには、kill を使用して CONT を親プロセスに送信します。
正しい
親プロセスPIDは、jobs -lによって報告されたPIDとは異なります。つまり、CONT信号を送信する必要があるプロセスは、jobs -lを使用して見つけたプロセスとは異なります。
間違っています。同じpidで、pgidと同じです。
CONT を親プロセスに送信すると、同じシグナルは子プロセスに適用されません。
正しい
bgコマンドを使用してプロセスを実行状態に戻し、CONT信号を親プロセスとすべての子プロセスに送信します。
はいが、親プロセスと子プロセスの両方が同じプロセスグループにある場合にのみ適用されます。また、各プロセスに対して順番にkill(2)を呼び出すのではなく、pgid(=プロセスグループリーダーのpid)の負数を使用して一度だけ呼び出し、カーネルに依存して信号をすべてのプロセスにルーティングします。そのグループ。
答え2
ここではこの動作を見ることはできません。
以下は、コマンドラインにそのまま入力したサンプルコードです。
bash -c 'echo This is parent $$; sleep 7; bash -c "echo This is child \$$; sleep 7; echo Child done"; echo This is parent $$ again; sleep 7'
メッセージが表示されたら、[プロセスの一時停止]を
This is child xx
クリックします。CtrlZ実際に一時停止していることを確認するには、7秒間待ってください。
これで
jobs -l
プロセスリーダー(親PID)が一覧表示されます。実際、この場合はジョブ番号を使用できます。%1
バックグラウンドでのプロセスの継続
kill -CONT %1
私は子供が絶えず終了し、親が終わるようにするのを見ました。
これは完全な実行結果です(>$
シェルプロンプトを含む)。
>$ bash -c 'echo This is parent $$; sleep 7; bash -c "echo This is child \$$; sleep 7; echo Child done"; echo This is parent $$ again; sleep 7'
This is parent 2004
This is child 10696
[1]+ Stopped bash -c 'echo This is parent $$; sleep 7; bash -c "echo This is child \$$; sleep 7; echo Child done"; echo This is parent $$ again; sleep 7'
>$ jobs -l
[1]+ 2004 Stopped bash -c 'echo This is parent $$; sleep 7; bash -c "echo This is child \$$; sleep 7; echo Child done"; echo This is parent $$ again; sleep 7'
>$ kill -CONT %1
>$ Child done
This is parent 2004 again
自動化されたテストツールを使用してより多くの実験をしたい場合は、kill -TSTP ...
キーボードで生成されたものと同じシグナリングを使用できます。CtrlZ