[Vienna-pm] anmerkungen ..

Peter J. Holzer hjp-vienna-pm-list at hjp.at
Fri May 25 10:59:05 PDT 2007


On 2007-05-25 18:09:18 +0200, gooly at gmx.at wrote:
> kurze Frage nach Einschätzungen..
> Ich hab meinen kleinen Server, der ab und zu Files aus der RAM-Disk an 
> remote-Clients (über $SOCKET) schicken soll. 
> Die Files sind zT gezippt zum Teil nicht.
> Um jetzt einerseits das Perl-Prg kleinzuhalten, andererseits den 
> Speicherverbrauch aus dem (24/7) Perl-Prg 'raus'-zuhalten (ich erinnere 
> mich an einen Thread zu Speicherfressern hier) habe ich mir etwas s.u. 
> ausgedacht. 
> 
> Ich bin aber ein bißchen unsicher, das Ganze schaut schon so einfach 
> aus, dass ich nicht ganz dran gkauben kann.

Doch, das ist so einfach. Duppen von Filedescriptoren auf STDOUT oder
STDIN ist Standard-Unix-Technik. Wenn Du auf der Commandline 

    unzip -p foo.zip > foo

tippst, macht die Shell im Prinzip nichts anderes.

> Denn wenn es wirklich so simpel ist, sollte das ein
> Perl-Standardfeature sein und in den tutorials stehen - oder?

Kommt in perlipc und perlopentut vor, allerdings nicht wirklich erklärt
(zumindest schien es mir beim kurzen Überfliegen eher zusammenhanglos in
der Gegend herumzustehen). Vielleicht haben die Autoren angenommen, dass
jeder Perl-Programmierer auch die Shell kennt und dass das Feature keine
weiteren Erklärungen braucht.


> foreach my $f ( liesFiles($FileDir) ) {
>    open( SAVEOUT, "<&STDOUT" ) or warn "can't save stdout: $!\n";
>    open( STDOUT, "<&", $SOCKET )  or warn "can't dup to stdout:$!\n";

Das ist verwirrend. Du öffnest hier STDOUT zum Lesen. Funktioniert zwar
trotzdem, aber IMHO nur deswegen, weil die Information das exec nicht
übersteht (der darunter liegende Filedescriptor wird nur dupliziert und
bleibt damit zum Lesen und Schreiben geöffnet).

>    if ($f =~ /\.zip/) {
>       system('unzip', '-p', $f );
>    } else {
>       system('cat', $f);
>    }
>    open( STDOUT, "<&SAVEOUT" ) or warn "can't restore stdout: $!\n";

Und da auch. Kannst Du danach noch auf STDOUT schreiben?

> Also das mit unzip klappt.
> Das mit cat hab ich noch nicht probiert. Frage dazu gäbe es zu 'cat' 
> einen bessere Alternative?
> Kann man so wirklich im aufrufenden Perl-Programm den Speicherverbrauch 
> vermeiden, den zB ein
> 	my $str;
> 	open F, "<$file" or warn "$!\n";
> 	read F, $str, (-s $file);
> 	close(F);
> 	...
> von der Größe des Files verursachen würde?

Ja. Die Daten gehen ja gar nie durch Dein Programm durch, zip bzw. cat
gibt das direkt auf den Socket aus und terminiert dann. Selbst wenn zip
bzw. cat das File als ganzes in den Speicher lesen würden, wäre der
Speicher danach wieder frei, während das bei read F, $str, (-s $file);
nicht notwendigerweise der Fall ist (Perl gibt Speicher ungern an das OS
zurück - vielleicht braucht es ihn ja später wieder).

Eine sinnvolle Perl-Variante wäre

	my $str;
	open F, "<", $file" or warn "$!\n";
	while (read F, $str, 0x1_0000) {
	    print $socket $str;
	}
	close(F);

(auch "while (<F>) print }" würde funktionieren, braucht aber soviel
Speicher wie die längste Zeile lang ist, was bei binären Files ziemlich
unabschätzbar ist)

Eine Methode, Memory-Leaks zu vermeiden, ist es zu forken und die
eigentliche Arbeit im Kind-Prozess zu machen. Wenn der beendet wird, ist
alles wieder beim alten. Das hat bei Servern auch den Vorteil, dass man
mehrere Clients gleichzeitig bedienen kann (Ja, das geht auch anders,
aber "forking server" ist eine der einfachsten Varianten).

	hp

-- 
   _  | Peter J. Holzer    | I know I'd be respectful of a pirate 
|_|_) | Sysadmin WSR       | with an emu on his shoulder.
| |   | hjp at hjp.at         |
__/   | http://www.hjp.at/ |	-- Sam in "Freefall"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://mail.pm.org/pipermail/vienna-pm/attachments/20070525/d3b8385e/attachment.bin 


More information about the Vienna-pm mailing list