Linux, waitpid, WNOHANG und zombies
Ich muss in der Lage sein:
- fork einen Prozess und machen es execvp (ich hab das)
- überprüfen Sie, ob der untergeordnete Prozess execvp erfolgreich war (weiß nicht wie)
- überprüfen Sie, ob der untergeordnete Prozess beendet (Probleme)
Ich bin Gabelung ein Prozess und ich habe keine Möglichkeit zu prüfen, ob die Kinder die execvp gearbeitet hat oder nicht. Wenn es fehlgeschlagen ist ich muss in der Lage sein zu wissen, dass es fehlgeschlagen ist. Derzeit bin ich mit
-1 != waitpid( pid, &status, WNOHANG )
Aber es scheint, dass, wenn die execv des pid-Prozess fehl, ist der waitpid nicht -1 zurück.
Wie könnte ich das überprüfen? Ich lese die waitpid-Mann-Seite, aber es ist nicht klar zu mir; vielleicht ist mein Englisch nicht gut genug ist.
EDIT: um zu klären:
Ich Baue mir mein eigenes terminal für ein Haus Arbeiten. Ich brauche, um die als Eingabe ein Kommando-string, sagen wir, "ls" und dann habe ich, um den Befehl auszuführen.
Nachdem das Kind die Gabeln, die das Kind fordert, execvp, um den Befehl auszuführen ( nachdem ich parse den string) und die Eltern brauchen, um zu überprüfen, ob es ein '&' am Ende des Befehls oder nicht.
wenn das Zeichen '&' ist nicht vorhanden am Ende des Befehls, dann die Eltern müssen für das Kind warten, um Sie auszuführen.
also muss ich wissen, wenn die execvp failed. Wenn es nicht gescheitert, dann die Eltern verwenden waitpid warten für das Kind, um es zu beenden die Ausführung. Wenn es fehlgeschlagen ist dann die Eltern nicht für das Kind warten.
- am besten Frage-Titel überhaupt.
- Es gibt ein paar Faktoren, die beeinflussen könnten Ihre Lösung hier: Was sind Sie
execvp
ing-Prozess in? Sie haben die Möglichkeit zu Bearbeiten? Ist es okay nicht zu wissen, ob die execvp failed bis das Kind verlässt? Wenn Sie eine detailliertere Problembeschreibung, wir könnten in der Lage sein, einen besseren Ratschlag geben. - Kann nicht senden Sie ein signal vom Kind zu den Eltern im Fall der besagten Fehler?
- Ich bearbeitet meine post, Thank u!
- In dieser situation, die Sie nicht wirklich brauchen, zu wissen, ob die execvp erfolgreich ist. Alles, was Sie tun müssen, ist zu entscheiden, ob die Verwendung
WNOHANG
fürwaitpid
. Wenn es ein &, dann verwenden Sie es. Verwenden Sie andernfalls eine gewisse Struktur zu überwachen, die hintergrund-tasks. - Eigentlich, überprüfen Sie heraus die Antwort, die ich gab, stackoverflow.com/questions/12824848/... - es gibt eine ziemlich anständige bit-code-Lösungen.
- danke! Aber jetzt hab ich ein anderes problem. Ich brauche zu implementieren, fg und bg ( Vordergrund und Hintergrund ) Arbeitsplätze. wenn ich einen Befehl auszuführen, ohne ein & am Ende, es ist ein Vordergrund-job und dafür ist der parent wartet für das Kind zu beenden. Ich muss in der Lage sein, um zurückzukehren die Ausführung für die Eltern, wenn SIGTSP signalisiert wird, in anderen Worten nach eine Strg+z gedrückt wird. gut, ich bin in der Lage zu stoppen den Vordergrund-Prozess, aber ich bin nicht in der Lage, um die Rückkehr der Ausführung an den Elternteil, und ich weiß nicht, warum. gibt es etwas, was ich tun muss ?
- Das hängt von Ihrer Umsetzung und Ihrem system. Ich könnte in der Lage sein zu helfen, aber es scheint, wie eine "neue Frage" ist die Art von situation.
- danke für deine Hilfe, ich habe eine neue Fragen :stackoverflow.com/questions/13485462/.... Danke!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer gemeinsamen Lösung zu #2 ist, eine pipe zu öffnen, die vor dem fork(), dann schreiben Sie es in das Kind nach dem exec. In der übergeordneten, zu einem erfolgreichen Lesen, bedeutet, dass die exec fehlgeschlagen; ein erfolgloser Lesen bedeutet, dass der exec gelungen ist und die schreiben nie stattgefunden hat.
Diese Weise können die Eltern eindeutig wissen, ob der exec war erfolgreich, und als ein Nebenprodukt, was die errno-Wert wurde, wenn nicht erfolgreich.
Wenn die exec erfolgreich war, wird der Kind-Prozess kann immer noch nicht mit einem exit-code, und die Prüfung des status der
WEXITSTATUS
makro geben Sie zu, dass Zustand als gut.HINWEIS: der Aufruf
waitpid
mit derWNOHANG
Flagge ist ungeblockt, und Sie müssen, um eine Umfrage der Prozess, bis eine gültige pid zurückgegeben wird.FD_CLOEXEC
. Das Rohr ist geschlossen, das Kind, wennexecv*
gelingt. Eine Lesen zurück 0 für EOF.pipe2
mitO_CLOEXEC
stattpipe
gefolgt vonfcntl
. Es ist nicht nur effizienter, sondern auch setzt das close-on-exec-flag atomar mit dem öffnen der pipe, also ist es sicher für multi-Threading verwenden, wo auch andere threads, die möglicherweise das ausführen externer Befehle zu. Jetztpipe2
ist eine Erweiterung, aber es ist bereits eine Zusage für die Aufnahme in die nächste version von POSIX.Einem exec-Aufruf sollte nicht zurückkehren, wenn es ihm gelingt, denn es ersetzt den aktuellen Prozess Bild mit einem anderen ein, also wenn es bedeutet das ein Fehler aufgetreten:
Lassen, dass der übergeordnete Prozess wissen, ob
exec
fehlgeschlagen Lesen Sie den status der Kind-Prozess:Verwenden und dann die
WEXITSTATUS(status)
makro, aus der man-page:Hinweis: die Letzte Aussage bedeutet, wenn
exec
gelingt und führt den Befehl erhalten Sie den exit-status desmain()
Funktion des Befehls, in anderen Worten man kann nicht zuverlässig sagen, der Unterschied zwischen einer fehlgeschlagenenexec
und einen fehlgeschlagenen Befehl diese Weise, also es hängt davon ab, ob das wichtig für dich ist.Anderes Thema:
Müssen Sie rufen Sie
wait()
auf der Kind-Prozess an einem gewissen Punkt in Ihrem Programm, unabhängig von der&
zu vermeiden, dass der Kind-Prozess in einem zombie Zustand,Hinweis: Wenn Sie die
WNOHANG
es bedeutet, dasswaitpid()
wird sofort zurück, wenn kein Prozess seinen Status gewechselt hat, d.h. es wird nicht blockieren, ich nehme an, Sie wissen, die verwenden, ansonstenwait()
oder rufen Siewaitpid()
als Teil der main-loop.execvp
ed, bevor ich Sie senden Signale oder andere Informationen verwalten, und damit nicht warten können, bis es tatsächlich zu beenden?waitpid
ausgeführt wird und zurückkehrt, bevor dieexecvp
scheitert, wird es yeild ein false positive ist.waitpid
nicht zurück, es sei denn, ein Kind ist sich der Zustand ändertfork
,exec
Überprüfenexec
Erfolg, Informationen Senden, warten Sie, bis finish.WNOHANG
, was bewirkt der wait-Funktionen, um "sofort zurückkehren, wenn kein Kind beendet wurde". Und eine Lösung, die nicht behandeln Sonderfälle, vor allem in der parallelen Verarbeitung, ist aber nicht wirklich eine Lösung. Ich versuche nicht gemein sein, ich versuche nur, um sicherzustellen, dass OPs Frage ist richtig beantwortet.WNOHANG
ist nicht in einer Schleife aufgerufen ?WNOHANG
als die offensichtliche warten, aber ja, ich werde zu aktualisieren, dass