これらのプロセスの概念がどのように関連付けられるか-background
、zombie
、daemon
およびwithout controlling terminal
?
特にcontrolling terminal
ですが、Linuxに関する記事を読む子供に嘘をつくことなく説明する必要がある場合など、話をするための情報はまだあまりありません。
更新#1:たとえば(それが本当かどうかはわかりません)
background
-zombie
-フォアグラウンドプロセスをzombie
にすることはできません。これは、zombie
が親なしで残されたバックグラウンドプロセスであるためですdaemon
-without ctty
-すべてのdaemons
はctty
なしで実行されますが、ctty
なしのすべてのプロセスはdaemons
ではありませんbackground
-daemon
-background process
を取得して、インタラクティブに再実行できます。daemon is not
zombie
-without ctty
-zombie
が添付されているかどうかに関係なく、ctty
は無関心ですbackground
-without ctty
-processes
がctty
を持っているときにバックグラウンドに送信され、ctty
が取得されるとデーモンになるか死ぬ簡単に言うと、リンクがあります。
終了/終了したが、その親が(wait()
システムコールを使用して)終了をまだ確認していないプロセス。デッドプロセスはプロセステーブルに保持されるので、親には、子プロセスの子が終了したこと、および終了ステータスが通知されます。通常、子供をフォークするプログラムは終了時に終了ステータスも読み取るため、親が停止しているかバギーの場合にのみゾンビが表示されます。
見る:
これらは、端末で実行されているシェルのコンテキストでのジョブ制御に関連しています。ユーザーがログインし、セッションが開始され、端末(制御端末)に結び付けられ、シェルが開始されます。シェルは次にプロセスを実行し、ユーザーが望むようにフォアグラウンドとバックグラウンドでそれらを送信します(プロセスの開始時に_&
_を使用し、_^Z
_で停止し、fg
とbg
)。端末からの読み取りまたは書き込みを行うと、バックグラウンドのプロセスが停止します。フォアグラウンドのプロセスは、端末で_^C
_がヒットした場合に割り込み信号を受け取ります。 (これらの信号を処理するのはカーネルのターミナルドライバーです。シェルは、フォアグラウンドまたはバックグラウンドに送信されるプロセス(グループ)を制御します。
見る:
デーモンとして実行されているプロセスは、通常、特定の端末(またはログインセッション、またはシェル)に関連付けるべきではありません。端末が閉じた場合に信号を受信しないように、制御端末を持っていてはなりません。また、通常、端末でI/Oを実行したくありません。コマンドラインからデーモンを開始するには、端末へのすべての関係を解除する必要があります。つまり、制御セッションを取り除くために(上記のジョブ制御の意味で)新しいセッションを開始し、端末へのファイルハンドルを閉じます。もちろん、init
、systemdなどのログインセッション以外で開始されたものには、これらの結びつきはありません。
デーモンには制御端末がないため、ジョブ制御の対象ではなく、ジョブ制御の意味で「フォアグラウンド」または「バックグラウンド」にあることは適用されません。また、デーモンは通常init
に親を変更し、終了時にそれらをクリーンアップするため、通常はデーモンをゾンビとして認識しません。
見る:
これらのタイプのプロセス間のdifferencesに重点を置いた私の説明です(短いが有益です):
zombie
-終了した(実行が終了した)が、プロセステーブルにエントリがあるプロセス。 注:zombieプロセスにはparentそして通常、その存在の要点は、親プロセスに子の実行結果(終了コードなど)を知らせることです。disowned process
(制御端末なし)-ユーザーによって明示的にdisown
されたか、親プロセスツリーから切り離されるように設計されたプロセス。親プロセスが実行を終了しても、引き続き実行されます。たとえば、ユーザーがリモートマシンにssh
'edし、Webサーバーなどを起動してから、disown
を実行してssh
セッションを終了しました。プロセスは親プロセスツリーの一部ではなくなったため、引き続き実行されます。プロセスは、Nohup
を使用して実行しないこともできます。background process
-バックグラウンドで実行-出力をユーザーのttyに分割しません。最後に&
を使用して実行されたか、設計によりバックグラウンドに分岐しました。プロセスをバックグラウンドに送信する他のオプションは、プロセスを開始してctrl+z
を押すことです。ただし、親プロセスが終了すると、バックグラウンドで実行されている子も終了します(note by @psusi-以前の事実は、ユーザーが端末から開始したプロセスでのみ当てはまります。それ以外の場合、子プロセスは「孤児」であり、親としてinitプロセス(pid 1)を取得します)。daemon
-バックグラウンドプロセスとよく似ています。また、バックグラウンドで実行されますが、おそらく(設計上)暗黙的にフォークされました。通常、それはバックグラウンドに静かに座って、いくつかのイベントが発生するのを待ってから、実際の作業(着信接続など)を行います。実際、daemonは、disowned(おそらく)とbackgroundプロセスによって異なります。この説明がこれらのタイプのプロセスを区別するのに役立つことを願っています。
ゾンビは実際には他の人とは関係ありません。これは単に終了したプロセスですが、その親プロセスはwaitpid()
などで終了ステータスをまだ読み取っていません。プロセスにバグがあるか停止していない限り、これらは表示されません。
daemonは、制御端末なしで実行されるプログラムです。通常、プログラムを実行すると、プログラム自体がfork()s
になり、親が終了するため、シェルはコマンドが終了したと判断し、子プロセスはターミナルから切り離されて、ログインセッションをエスケープします。親プロセスが終了したため、その親プロセスIDは1になります。これは、従来はinit
プログラム、または最近ではsystemd
です。このプロセスにより、ゾンビでオーバーランしないように、子供が死んだときに必ずその子供を刈り取ることができます。
プロセスは制御端末に関連付けることができます。これは、通常、プロセスが入力を取得し、出力を送信する場所です。端末は、接続されているプロセスにシグナルを送信することもでき、プロセスグループをフォアグラウンドグループとして識別します。 フォアグラウンドグループにあるプロセスは、端末から入力を読み取ることができ、Ctrl-CおよびCtrl-Zを押すと、SIGINTおよびSIGSUSPシグナルが送信されます。端末から読み取ろうとするフォアグラウンドグループにないプロセスは、SIGTSTPで中断されます。
シェルは、実行するように要求するパイプラインコマンドごとに異なるプロセスグループを作成し、ジョブをフォアグラウンドとバックグラウンド間で移動するためにフォアグラウンドグループをシフトします。コマンドを実行すると、通常、シェルは新しいプロセスグループを作成し、そのグループをフォアグラウンドグループにします。末尾に&
を付けると、シェルはフォアグラウンドグループをそのまま残し、新しいグループがバックグラウンドに配置されます。 Ctrl-Zを押すと、SIGSUSPがフォアグラウンドグループに送信されます。これにより、ほとんどのコマンドが一時停止しますが、シェルは一時停止する代わりに、アクティブなフォアグラウンドグループをそれ自体に変更して、新しいコマンドを要求できるようにします。
bg
コマンドは、SIGCONPをプロセスグループに送信して、SIGSUSPで中断された後にバックグラウンドで実行を再開できるようにします。 fg
はforeground groupをバックグラウンドですでに実行されている既存のグループの1つに変更し、フォアグラウンドにします。