2012-05-09 11 views
24

Sposób A fork() a proces B.Czy można przyjąć proces?

Sposób A narzędzia, a tym samym przyjmuje init B.

watchdog tworzy proces C.

jest jakoś możliwe C do przyjęcia B z init?


Aktualizacja:

A byłoby jeszcze możliwe mieć C przyjąć B bezpośrednio (gdy A umiera), jeśli C powstały przed żyje, bez init staje się pośrednim rodzic B ?


Update 1:

Również chciałbym wdzięczni za wszelkie uwagi na temat, dlaczego mając możliwośc przyjęcia procesie drogę opisałem byłoby złą rzeczą niemożliwe lub trudne do wdrożenia.


Update-2 - Sprawa zastosowanie (rodzic i dzieci odnoszą się do procesu (ów)):

Mam app przy użyciu rodzica zarządzać całą masę dzieci, które opierają się na system zarządzania rodzicem. Aby wykonać to zadanie, rodzic polega na otrzymaniu powiadomienia przez dziecko, co następuje po otrzymaniu powiązanego sygnału SIGCHLD.

Jeśli rodzic sam zginie z powodu jakiegoś wypadku (włączając w to uszkodzenie), muszę zrestartować całą "rodzinę", ponieważ nie jest możliwe wyzwolenie czegoś na zakończenie dziecka (co może również wynikać z błędu segfault).

W takim przypadku muszę usunąć wszystkie dzieci i wykonać pełny restart systemu.

Możliwym sposobem na uniknięcie tej sytuacji byłoby zainstalowanie procedury zastępczej, która mogłaby przejąć rolę zmarłego rodzica ... - gdyby mogła ponownie odbierać sygnały dla dzieci z kroku!

+2

Według mojej wiedzy, nie. –

+0

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

+0

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

Odpowiedz

8

Nie ma żadnego sposobu, aby można było wykonać Reparenting w sposób opisany przez użytkownika.

+0

Chociaż trudno mi zaakceptować to, co piszesz, akceptuję twoją odpowiedź ... ;-) - w każdym razie, zastanawiam się, czy istnieją jakieś dobre powody, aby nie mieć takiej możliwości. A może dlatego, że nikt jej nie potrzebuje, więc nikt go jeszcze nie wdrożył? @als – alk

+0

@alk: Jeśli uważasz, że trudno to zaakceptować, nie akceptuj tego, pozwól q być lub może dodać nagrodę. –

+1

Masz rację. Nie akceptuję twojej odpowiedzi, ponieważ może to może skłonić kogoś do komentowania tego pytania. @als – alk

15

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.

+0

Dziękuję za wyjaśnienia. Rozumiem, że nie można po prostu przejąć nadzoru nad procesem. Ale dla drugiej drogi wyjścia (wymienionej pod "Aktualizacją" w moim pytaniu) może istnieć możliwość zarejestrowania istniejącego procesu jako procesu zapasowego, aby wprowadzić krok (w odniesieniu do nadrzędności) w przypadku śmierci innego procesu, aby jego dzieci następnie nie zostaną przyjęte przez "init", ale przez (poprzednio zarejestrowany) zapasowy proces. – alk

+0

Edytowane z dalszą odpowiedzią. –

+0

Jeszcze raz dziękuję za przekazanie swoich myśli.Jeśli chodzi o ponowne zwracanie się do dziadków, to z pewnością widzę, że nie można tego uczynić domyślnym zachowaniem, ponieważ wiele istniejących implementacji (i wzorca) polega na tym, że dzieci tracą swojego rodzica, aby zostać adoptowanym przez init. – alk

Powiązane problemy