25

プロセス A はfork()プロセス B です。

プロセス A は終了し、したがってinitB を採用します。

ウォッチドッグはプロセス C を作成します。

CがBからBを採用することはどういうわけか可能initですか?


更新

initそれとも、B の中間の親になることなく、A が亡くなる前に C が作成された場合、C に B を直接 (A が亡くなったときに) 採用させることさえ可能でしょうか?


更新-1:

また、私が説明した方法でプロセスを採用する可能性が悪いこと、または実装が困難または不可能である理由について、コメントをいただければ幸いです。


Update-2 - ユース ケース (親と子はプロセスを参照):

親の管理機能に依存している多くの子を管理するために、親を使用するアプリがあります。その仕事をするために、親は子の終了によって通知されることに依存しています。これは、関連するSIGCHLDシグナルを受信することによって行われます。

親自体が何らかの事故 (segfault を含む) で死亡した場合、「家族」全体を再起動する必要があります。これは、子の終了時に何かをトリガーすることが不可能になっているためです (これも segfault が原因である可能性があります)。

このような場合、すべての子プロセスを停止して、システム全体を再起動する必要があります。

この状況を回避するための可能なアプローチは、死んだ親の役割を引き継ぐことができるスペアプロセスを用意することです... -ステップの子のSIGCHLDシグナルを再び受信できる場合!

4

3 に答える 3

16

いいえ、絶対に不可能です。いくつかの厄介な競合状態がなければ、実装することもできませんでした。これらの API を作成する POSIX 担当者は、固有の競合状態を伴うものを作成することは決してありません。そのため、気にしなくても、カーネルがすぐにそれを取得することはありません。

1 つの問題は、pid が再利用されることです (それらは希少なリソースです!)、ハンドルを取得したりロックしたりすることもできません。それはただの数字です。たとえば、コードのどこかに、親を変更したいプロセスの pid を入れる変数があるとします。次に、 を呼び出しますmake_this_a_child_of_me(thepid)。その場合はどうなりますか?その間に、他のプロセスが終了し、他のプロセスthepidを参照するように変更された可能性があります。おっとっと。make_this_a_child_of_meUNIX がプロセスを処理する方法を大幅に再構築しない限り、APIを提供する方法はありません。

子 pid に対する ingの処理全体は、まさにこの問題を防ぐためのものであることに注意してくださいwait。pid が再利用されるのを防ぐために、ゾンビ プロセスがプロセス テーブルにまだ存在します。親は、プロセスが終了して子 pid が再利用されることはないと確信して、その pid で子を参照できます。子プロセスが終了した場合、その pid は、親プロセスが SIGCHLD をキャッチするか待機するまで予約されます。プロセスがリープされると、その pid は、他のプログラムが fork したときに使用を開始できるようにすぐに取得できるようになりますが、親はそれについて既に知っていることが保証されています。

更新への応答: プロセスが次の祖先に再親化される、より複雑なスキームを検討してください。明らかに、これはすべての場合に実行できるわけではありません。ゾンビを確実に回避するために、子供の所有権を剥奪する方法が必要になることがよくあるからです。init はその役割を十分に果たします。したがって、プロセスがその孫 (またはそれ以下) を採用するかどうかを指定する何らかの方法が必要です。この設計の問題は、最初の状況とまったく同じです。競合状態が発生します。

再び pid によって実行された場合、祖父母は競合状態にさらされます: 親だけが pid を取得できるため、親だけが pid がどのプロセスに関連するかを本当に知っています。祖父母は刈り取ることができないため、孫のプロセスが採用しようとしていたものから変更されていないことを確認できません (または、仮想 API の動作に応じて、否認します)。負荷の高いマシンでは、プロセスが数分間 CPU から解放されるのを止めるものは何もなく、その間に全体の負荷が変化した可能性があることを覚えておいてください。理想的ではありませんが、POSIX はそれを考慮しなければなりません。

最後に、この API は pid では機能せず、一般的には「すべての孫を私に送る」または「それらを init に送る」と言うだけだとします。子プロセスが生成された後に呼び出されると、以前と同じように競合状態になります。以前に呼び出された場合、すべてが役に立ちません。アプリケーションを少し再構築して、同じ動作を得ることができるはずです。つまり、子プロセスの生成を開始する前に、誰が親になるべきかを知っているのであれば、最初から正しい方法でそれらを作成することができないのはなぜでしょうか? Pipes と IPC は、実際に必要なすべての作業を行うことができます。

于 2012-05-11T11:00:01.287 に答える
8

いいえ、説明した方法で親の変更を強制する方法はありません。

于 2012-05-09T16:13:21.740 に答える