Nie, zdecydowanie nie jest to możliwe. Nie można go też wdrożyć bez nieprzyjemnych warunków wyścigowych. Użytkownicy POSIX, którzy tworzą te interfejsy API, nigdy nie stworzyliby czegoś z nieodłącznym stanem wyścigowym, więc nawet jeśli się nie przejmujesz, twoje jądro nie dostanie go w najbliższym czasie.
Jednym z problemów jest to, że pyski są ponownie wykorzystywane (są rzadkim zasobem!), A także nie można uzyskać ani blokady, ani blokady; to tylko liczba. Tak więc, powiedzmy, gdzieś w kodzie, masz zmienną, w której umieszczasz pid procesu, który chcesz powtórzyć. Następnie zadzwoń pod numer make_this_a_child_of_me(thepid)
. Co by się wtedy stało? W międzyczasie inny proces mógł zostać zakończony i zmieniona thepid
, aby odnieść się do innego procesu! Ups. Nie może istnieć sposób na zapewnienie interfejsu API make_this_a_child_of_me
bez dużej restrukturyzacji sposobu obsługi procesów przez system UNIX.
Zauważ, że cała sprawa z wait
na pidzie podrzędnym jest właśnie w celu zapobieżenia temu problemowi: proces zombie nadal istnieje w tabeli procesu, aby zapobiec ponownemu użyciu pid. Rodzic może następnie odwołać się do swojego dziecka przez jego pid, mając pewność, że proces nie zakończy się i ponownie użyje pid dziecka. Jeśli dziecko wyjdzie, jego pid jest zarezerwowany, dopóki rodzic nie zapisze SIGCHLD lub nie zaczeka na niego. Gdy proces jest zbierany, jego pid jest gotowy do natychmiastowego pobrania, aby inne programy zaczęły używać po rozwidleniu, ale rodzic ma pewność, że już o tym wie.
Odpowiedź na aktualizację: rozważ bardziej skomplikowany schemat, w którym procesy są ponownie przekazywane do następnego przodka. Oczywiście, nie da się tego zrobić w każdym przypadku, ponieważ często chcecie uniknąć wyrzeczenia się dziecka, aby uniknąć zombie. init bardzo dobrze spełnia tę rolę. Musi więc istnieć jakiś sposób, aby proces określał, czy zamierza adoptować, czy też nie, wnuki (lub niższe). Problem z tym projektem jest dokładnie taki sam, jak w pierwszej sytuacji: ty nadal uzyskać warunki wyścigu.
Jeśli zrobi to ponownie pid, wówczas dziadek wystawia się na wyścig: tylko rodzic jest w stanie zebrać pid, więc tylko rodzic naprawdę wie, z którym procesem przechodzi pid. Ponieważ dziadek nie może żąć, nie może być pewien, że proces wnuka nie zmienił się od tego, który zamierzał przyjąć (lub odrzucić, w zależności od tego, jak działałby hipotetyczny API). Pamiętaj, że na mocno obciążonej maszynie nic nie stoi na przeszkodzie, aby proces został usunięty z CPU przez kilka minut, a całe obciążenie mogło się zmienić w tym czasie! Nie idealne, ale POSIX musi to wyjaśnić.
Wreszcie, załóżmy, że ten interfejs API nie działa przez pid, ale generalnie mówi: "wyślij mi wszystkie wnuki" lub "wyślij je do init". Jeśli zostanie wywołany po zrobieniu procesów potomnych, wtedy warunki wyścigu będą takie, jak wcześniej. Jeśli jest to wcześniej wywoływane, cała sprawa jest bezużyteczna: powinieneś być w stanie trochę zmienić swoją aplikację, aby uzyskać takie samo zachowanie. Oznacza to, że jeśli wiesz, zanim uruchomisz procesy potomne, których rodzic powinien być rodzicem, dlaczego nie możesz po prostu stworzyć ich we właściwy sposób? Rury i IPC naprawdę są w stanie wykonać wszystkie wymagane prace.
Według mojej wiedzy, nie. –
Dzieci mogą się schować, jeśli odziedziczą po prostu "odczytany" koniec fajki wykonanej przez rodzica. Koniec "przeczytania" wybierze czytelność (dla EOF) po śmierci rodzica, zdarzenie OI, na które każde dziecko może się zatrzymać i zareagować. – pilcrow
Problem polega na tym, że nie chcę sprowadzać dzieci. Chciałbym mieć możliwość zastąpienia martwego rodzica (jeśli chodzi o możliwość otrzymywania ich SIGCHLD, na wypadek gdyby zakończyli), przez proces krok-rodzic. @pilcrow – alk