バックグラウンドプロセス自体は可能ですか?
Perlおよび/またはCの実装は何ですか?
ベストアンサー1
私はここで文字通りの質問に答えようとしています。できますか?プロセス背景それ自体フォーク自体とは対照的に、実行は子プロセスで継続して終了するため、これを待っているプロセスはここですでに他のプロセスによって処理された実行を再開できます。
ここでは、まず用語について説明します。
背景は通常、対話型シェルのジョブ制御を表します。
追加のコマンドを使用してコマンドを実行するのと同じです&
。またはCtrl+を押してZ実行しますbg
。
働くプロセスなしプロセスグループ。実行時:
$ ps -ej | grep -w "$$" & echo "$!"
35131
19152 19152 19152 pts/0 00:00:00 zsh
35130 35130 19152 pts/0 00:00:00 ps
35131 35130 19152 pts/0 00:00:00 grep
これはps | grep
働く(リーダーは実行中のプロセスですps
が、実行中のプロセスも含む35130プロセスグループを介して達成されますgrep
。)プロセスはバックグラウンドに配置されます。
背景ここで意味するものは次のとおりです。
- シェルはジョブが終了するのを待ちません。プロンプトに戻り、ジョブの実行中にさらにコマンドを入力できます。
- 端末装置ドライバは、プロセスグループがフォアグラウンドにないことを知らせた。したがって、このプロセスグループのプロセスには端末からデータを読み取る権限がなく(グループ内のプロセスの1つでも端末からデータを読み取ろうとすると、グループ内のすべてのプロセスが中断されます)
^C
//^Z
の影響を受けません^\
。など。 - シェルは内部作業テーブルにジョブを入力し、現在の背景にあるものとして記録します。
今背景表現は、時々、端末操作制御の外部で使用される。
これを行うとき:
cmd1 | cmd2 & pid=$!
somecommand
wait
スクリプトにはジョブ制御はありません。スクリプトが対話型シェルを介して端末で実行されると、他のコマンドと同様に、スクリプトの実行方法に応じてそれ自体が前景または背景に移動されます。
ただし、cmd1 | cmd2
スクリプトを解釈するシェルは対話型シェルではないため、スクリプトの内容はバックグラウンドに配置されません。
^Cを押すとスクリプトを実行しているシェルが終了し、cmd1
^ cmd2
Zを押すと一時停止します。cmd1 | cmd2
バックグラウンドで始めるより非同期で実行されます。。
バックグラウンドで開始されたタスクとの比較インタラクティブエンクロージャ、専用1もう終わりました。パイプを実行するためのプロセスグループは作成されませんでした。
さて、この事実が明確になったら、プロセスをバックグラウンドに配置できますか?
ちょうどいい働くまさかプロセスこれを文脈に合わせて説明すると、このプロセスに関する質問は次のとおりです。
- 私は端末に接続されたセッションに参加していますか? (作業制御は意味がありますか?)
- 私だけがそうなのでしょうか、それとも私のプロセスグループに別のプロセスがあるのでしょうか?
- 私のプロセスグループはすでにフォアグラウンドにありますか、それともバックグラウンドにありますか?
- 私のプロセスグループはインタラクティブシェルで待機しますか?
これらすべての質問に「はい」と答えることができる場合、つまり端末の対話型シェルから単純なコマンド(パイプや複合コマンドの一部ではない)で呼び出される場合は、次のものが必要です。 (1)Tellシェルが私たちを待つのを止める待機プロセス、(2)プロセスグループがもはや前景プロセスグループではないことを端末に知らせ、に指示します。背景。
終了または停止する以外に、他のプロセスにユーザーを待つように指示することはできません。この場合、プロセスは信号を受信または停止しますSIGCHLD
。wait*()
呼び出すと、現在実行中の操作が何でも返されます。
ただし、SIGTSTP信号(時刻に送信されたのと同じ信号)またはSIGSTOP(傍受不可能)を送信して自分自身を一時停止することができます^Z
。この場合、すべての(1)、(2)、(3)が自動的に発生します。状態は停止する変えるバックグラウンドで実行。
これで一時停止しているため、実行できなくなり、再起動できません。
ただし、(pidにSIGCONTを送信することによって)中断される前に、一定期間にわたって独自に再開される子プロセスをフォークできます。
実行を再開すると、シェルは SIGCHLD を再度受け取り、(3) シェルは現在の状態を認識します。走るこれは信号処理の開始時にバックグラウンドで発生します。
たとえば、次のように実装しますsh
。
$ sh -c 'echo running in foreground; sleep 1
(sleep 1; echo resuming my parent; kill -s CONT "$$") &
echo stopping; kill -s STOP "$$"
echo resumed
sleep 30
echo finished'; echo "$?"
running in foreground
stopping
147
zsh: suspended (signal) sh -c
$ resuming my parent
resumed
$ jobs
[1] + running sh -c
$ finished
[1] + done sh -c
kill(0, SIGSTOP)
(kill -s STOP 0
in)を使用してジョブ全体を一時停止することも可能ですsh
が、まだ開始されておらず、未知のプロセスの実行フローに影響を与えるため、プロセスはそうするのが正しいですか?
sh -c 'echo running in foreground
perl -MPOSIX -le "setpgid 0,0; # leave the process group before it is suspended
sleep 2;
print q(resuming the process group of my parent);
kill q(CONT), - shift@ARGV
" "$(ps -o pgid= -p "$$")" &
sleep 1
echo stopping my process group; kill -s STOP 0
echo process group resumed
sleep 30
echo finished' | cat