いいえ、絶対に不可能です。いくつかの厄介な競合状態がなければ、実装することもできませんでした。これらの API を作成する POSIX 担当者は、固有の競合状態を伴うものを作成することは決してありません。そのため、気にしなくても、カーネルがすぐにそれを取得することはありません。
1 つの問題は、pid が再利用されることです (それらは希少なリソースです!)、ハンドルを取得したりロックしたりすることもできません。それはただの数字です。たとえば、コードのどこかに、親を変更したいプロセスの pid を入れる変数があるとします。次に、 を呼び出しますmake_this_a_child_of_me(thepid)
。その場合はどうなりますか?その間に、他のプロセスが終了し、他のプロセスthepid
を参照するように変更された可能性があります。おっとっと。make_this_a_child_of_me
UNIX がプロセスを処理する方法を大幅に再構築しない限り、APIを提供する方法はありません。
子 pid に対する ingの処理全体は、まさにこの問題を防ぐためのものであることに注意してくださいwait
。pid が再利用されるのを防ぐために、ゾンビ プロセスがプロセス テーブルにまだ存在します。親は、プロセスが終了して子 pid が再利用されることはないと確信して、その pid で子を参照できます。子プロセスが終了した場合、その pid は、親プロセスが SIGCHLD をキャッチするか待機するまで予約されます。プロセスがリープされると、その pid は、他のプログラムが fork したときに使用を開始できるようにすぐに取得できるようになりますが、親はそれについて既に知っていることが保証されています。
更新への応答: プロセスが次の祖先に再親化される、より複雑なスキームを検討してください。明らかに、これはすべての場合に実行できるわけではありません。ゾンビを確実に回避するために、子供の所有権を剥奪する方法が必要になることがよくあるからです。init はその役割を十分に果たします。したがって、プロセスがその孫 (またはそれ以下) を採用するかどうかを指定する何らかの方法が必要です。この設計の問題は、最初の状況とまったく同じです。競合状態が発生します。
再び pid によって実行された場合、祖父母は競合状態にさらされます: 親だけが pid を取得できるため、親だけが pid がどのプロセスに関連するかを本当に知っています。祖父母は刈り取ることができないため、孫のプロセスが採用しようとしていたものから変更されていないことを確認できません (または、仮想 API の動作に応じて、否認します)。負荷の高いマシンでは、プロセスが数分間 CPU から解放されるのを止めるものは何もなく、その間に全体の負荷が変化した可能性があることを覚えておいてください。理想的ではありませんが、POSIX はそれを考慮しなければなりません。
最後に、この API は pid では機能せず、一般的には「すべての孫を私に送る」または「それらを init に送る」と言うだけだとします。子プロセスが生成された後に呼び出されると、以前と同じように競合状態になります。以前に呼び出された場合、すべてが役に立ちません。アプリケーションを少し再構築して、同じ動作を得ることができるはずです。つまり、子プロセスの生成を開始する前に、誰が親になるべきかを知っているのであれば、最初から正しい方法でそれらを作成することができないのはなぜでしょうか? Pipes と IPC は、実際に必要なすべての作業を行うことができます。