Prozesskommunikation

23/01/2012 - 10:44 von Stefan+Usenet | Report spam
Ich habe da eine Klasse, um Programme via proc_open() aufzurufen, stdout
und stderr zu erfassen und die Texte gemeinsam mit dem return value
zurueckzugeben. Die ersten, naiven Versuche fanden mit blocking I/O statt,
bis irgendwann wahlweise stdout oder stderr zu lang dafuer wurden; momentan
sieht die Geschichte so aus:

| $descriptors = array(
| 0 => array('pipe', 'r'), # stdin
| 1 => array('pipe', 'w'), # stdout
| 2 => array('pipe', 'w'), # stderr
| );
|
| $handle = proc_open($this->cmd, $descriptors, $pipes, NULL, $this->environment);
|
| stream_set_blocking($pipes[1], 0);
| stream_set_blocking($pipes[2], 0);
|
| fwrite($pipes[0], $string);
| fclose($pipes[0]);
|
| while (!feof($pipes[1]) || !feof($pipes[2])) {
| if (!feof($pipes[1])) $this->stdout .= fread($pipes[1], 8192);
| if (!feof($pipes[2])) $this->stderr .= fread($pipes[2], 8192);
| }
|
| fclose($pipes[1]);
| fclose($pipes[2]);
|
| $this->retval = proc_close($handle);

Das funktioniert in jedem beliebigen Fall - und da die aufgerufenen
Programme vom Tempo her meist Kreise um PHP herum laufen, auch ohne
Schwierigkeiten.

Nun gibt es aber einen Fall, wo $this->cmd einige Stunden lang
CPU-Zeit verbraet und erst danach beginnt (groessere Mengen) Text an
stdout oder im Fehlerfall auch an stderr auszugeben. Waehrend der
Zeit haengt PHP nun in der Schleife und liest und liest... nichts.

Laesst sich das irgendwie effizienter gestalten, _ohne_ dabei den
normalen Anwendungsfall negativ zu beeinflussen?

Servus,
Stefan

http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Offizieller Erstbesucher(TM) von mmeike

Der grausame Freund erwartet Stefan. Und Sie?
(Sloganizer)
 

Lesen sie die antworten

#1 Torsten Zuehlsdorff
23/01/2012 - 11:36 | Warnen spam
On 23.01.2012 10:44, Stefan Froehlich wrote:

Nun gibt es aber einen Fall, wo $this->cmd einige Stunden lang
CPU-Zeit verbraet und erst danach beginnt (groessere Mengen) Text an
stdout oder im Fehlerfall auch an stderr auszugeben. Waehrend der
Zeit haengt PHP nun in der Schleife und liest und liest... nichts.

Laesst sich das irgendwie effizienter gestalten, _ohne_ dabei den
normalen Anwendungsfall negativ zu beeinflussen?



Mein erster Gedanke war: Wenn absehbar oder messbar nichts kommt, ist es
das Beste ebenfalls nichts zu tun.

Ich würde also einen optionalen (oder dynamischen) Timer einbauen, der
auf "nichts tun" mit sleep() reagiert.

Gruß,
Torsten

Ähnliche fragen