PHP: Wie kann ich I / O im Elternteil zugänglich halten, nachdem das Kind von pcntl_fork () abgeschlossen wurde?

725
Stilez

Ich verwende PHP und pcntl_fork (). Die Idee ist, dass das Elternteil sich verzweigt und pausiert, damit das Kind es abschließen kann. das Kind erledigt dann eine Aufgabe; Der übergeordnete Benutzer kann den Rückkehrcode für die Aufgabe oder den Status des untergeordneten Prozesses prüfen und entsprechend fortfahren.

(Die Aufgabe wird durch Forking vom übergeordneten übergeordneten Element isoliert, um sicherzustellen, dass das übergeordnete Element eine saubere Bereinigung ausführen kann, wenn die Aufgabe auf ein nicht zu findendes Laufzeitproblem wie beschädigte "include" -Dateien oder fehlende Schlüsselbibliotheken trifft. Daher wird der Abzweig grundsätzlich implementiert.) Einfache Prozessisolierung für den hoffentlich seltenen Fall, dass ein nicht einfangbarer Zustand zu Problemen führen kann

Das Problem ist also, dass nach pcntl_fork () beide Prozesse dieselben STDXXX-E / A-Deskriptoren verwenden. Sobald das untergeordnete Objekt seine Aufgabe beendet, werden die von ihm verwendeten E / A wie üblich geschlossen und daher für das übergeordnete Element geschlossen Nun, was bedeutet, dass Dinge wie echo (), die verwendet wurden, um die Interaktion des Elternteils fortzusetzen, plötzlich auch nicht mehr funktionieren.

Ich folge einem Tipp auf php.net und verwende Posix kill -9 im Kind anstelle von exit, so dass das Kind beendet wird, ohne IO zu schließen, das mit dem übergeordneten Element geteilt wird (und von diesem benötigt wird), aber es gibt einen ordentlicheren Weg, dies zu tun ?

Vielen Dank!

0
Hmm, Unix-Dateideskriptoren sind _nicht_ für einen Fork () freigegeben, und auch keine PHP-IO-Objekte. Die Ursache ist also komplexer. grawity vor 8 Jahren 0

1 Antwort auf die Frage

0
meuh

Vor dem können pcntl_fork()Sie die gewünschten Dateideskriptoren "dup" machen, indem Sie beispielsweise php://stdoutund php://stderr, oder öffnen php://fd/3. Siehe PHP- Protokolle .


Beachten Sie, dass ein untergeordnetes Objekt beim Schließen eines Dateideskriptors im übergeordneten Element nicht geschlossen wird. Nach einer Gabelung teilen die Prozesse denselben Zeiger auf geöffnete Dateien, Sie können jedoch nach dem Beenden des untergeordneten Elements noch Echo vom übergeordneten Element erhalten.

Das klingt vielversprechend, aber Bereiche wie Sitzungen und die erforderliche Manipulation dupierter STDXXX-Deskriptoren liegen etwas außerhalb meines derzeitigen Wissensbereichs, und die Seiten (auf php.net und opengropup.org) sind mir nicht so klar wie ich hoffen. Könnten Sie erklären, wie Sie dies mit einem kurzen "Gliederungs" -Beispiel machen? Es würde viel helfen. Stilez vor 8 Jahren 0
@Stilez beim Nachlesen Ihres Beitrags Ich bin nicht sicher, warum Sie etwas Besonderes tun sollten, da "close ()" in einem Kind die übergeordnete Kopie eines Dateideskriptors nicht beeinflusst. `pcntl_fork ()` soll das reale System `fork ()` nennen, was effektiv 'dup () `bei geöffneten Dateien bewirkt. meuh vor 8 Jahren 0
Ich habe nachgesehen, aber php.net scheint close () nicht als Befehl zu erkennen? Klar ist, dass, wenn ich exit () oder die () im Kind durch einen POSIX-Self-Kill -9 ersetzt habe, der Elternteil die Ausgabe mit Echo fortsetzen kann, wenn ich es nicht kann, also die Bereinigung während Normales Beenden von Kindern muss die vom Elternteil verwendeten STDXXX-Deskriptoren schließen oder beeinflussen. Ist es möglich, einen kurzen Überblick über einen Weg zu geben, um das Kind anders zu verlassen, oder die Deskriptoren dupden oder "trennen", so dass das austretende Kind diese Wirkung nicht hat? Es würde wirklich helfen. Stilez vor 8 Jahren 0
@Stilez Ich habe ein kleines CGI ausprobiert, bei dem das Kind das Exit ausführt, und das übergeordnete Element konnte das Echo (mit PHP / 5.5.24 unter Linux) fortsetzen, sodass ich in Ihrer Situation nicht weiterhelfen kann. Möglicherweise sendet Ihr Kind einen Header mit der Anzahl der Bytes zurück, die das Kind geschrieben hat. Die meisten Browser werden diese Länge respektieren und nicht darüber hinaus lesen, auch wenn der übergeordnete PHP-Server es geschafft hat, mehr Daten zu schreiben. meuh vor 8 Jahren 0