Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Perl/CGI » perl: buffering ausschalten

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
21.04.2006, 21:04 Uhr
kronos
Quotenfisch
(Operator)


Hallo,
habe ein Problem mit einem Perl-Skript:
Lass ich es in einem Terminal laufen, gibt es brav alles prints direkt aus. Wird die Ausgabe allerdings in eine Datei gepipet, so wird diese zwar sofort erstellt, aber kein bit geschrieben, bis das Skript terminiert. Dann alles auf einmal. Mit bash-Skripten habe ich das Problem nicht, kann das an Perl liegen?
Was kann man dagegen tun?
--
main($)??<-$<='?'>>2?main($-!!putchar(
(("$;99M?GD??(??/x0d??/a:???;a"+'?'/4)
??($??)+'?'/3-2-1+$%2)??''?')):'?';??>

Dieser Post wurde am 21.04.2006 um 21:04 Uhr von kronos editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
21.04.2006, 21:41 Uhr
Pler
Einer von Vielen
(Operator)


Hm. Mit Perl hab ich das auch noch nicht gemacht.
Das Problem ist aber ein allgemeines Problem, da Ausgaben in Dateien immer gepuffert sind. Bei der stdout ist es nur Zeilen-gepich denke mal uffert.
In C heisst das fflush(). Hab da jetzt aber auf anhieb auch nichts gefunden. Such mal nach flush / flushen oder so.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
21.04.2006, 21:47 Uhr
Pler
Einer von Vielen
(Operator)


7.12. Flushing Output
Problem
When printing to a filehandle, output doesn't appear immediately. This is a problem in CGI scripts
running on some programmer-hostile web servers where, if the web server sees warnings from Perl
before it sees the (buffered) output of your script, it sends the browser an uninformative 500 Server
Error. These buffering problems arise with concurrent access to files by multiple programs and when
talking with devices or sockets.
Solution
Disable buffering by setting the per-filehandle variable $| to a true value, customarily 1:

Code:
$old_fh = select(OUTPUT_HANDLE);
$| = 1;
select($old_fh);


Or, if you don't mind the expense, disable it by calling the autoflush method from the IO modules:

Code:
use IO::Handle;
OUTPUT_HANDLE->autoflush(1);


Discussion
In most stdio implementations, buffering varies with the type of output device. Disk files are block
buffered, often with a buffer size of more than 2K. Pipes and sockets are often buffered with a buffer size
between 1/2 and 2K. Serial devices, including terminals, modems, mice, and joysticks, are normally
line-buffered; stdio sends the entire line out only when it gets the newline.
Perl's print function does not support truly unbuffered output - a physical write for each individual
character. Instead, it supports command buffering, in which one physical write is made after every
separate output command. This isn't as hard on your system as no buffering at all, and it still gets the
output where you want it, when you want it.
Control output buffering through the $| special variable. Enable command buffering by setting it to a
true value. It has no effect upon input; see Recipes Recipe 15.6 and Recipe 15.8 for unbuffered input. Set
this variable to a false value to use default stdio buffering. Example 7.6 illustrates the difference.
Example 7.6: seeme

Code:
#!/usr/bin/perl -w
# seeme - demo stdio output buffering
$| = (@ARGV > 0);                    # command buffered if arguments given
print "Now you don't see it...";
sleep 2;
print "now you do\n";


If you call this program with no arguments, STDOUT is not command buffered. Your terminal (console,
window, telnet session, whatever) doesn't receive output until the entire line is completed, so you see
nothing for two seconds and then get the full line "Now you don't see it ... now you do". If you
call the program with at least one argument, STDOUT is command buffered. That means you first see
"Now you don't see it...", and then after two seconds you finally see "now you do".
The dubious quest for increasingly compact code has led programmers to use the return value of
select, the filehandle that was currently selected, as part of the second select:

Code:
       select((select(OUTPUT_HANDLE), $| = 1)[0]);


There's another way. The FileHandle and IO modules provide a class method called autoflush. Call it
with true or false values (the default value is true) to control autoflushing on a particular output handle:

Code:
use FileHandle;
STDERR->autoflush;                           # already unbuffered in stdio
$filehandle->autoflush(0);


If you're willing to accept the oddities of indirect object notation covered in Chapter 13, Classes, Objects,
and Ties, you can even write something reasonably close to English:

Code:
use IO::Handle;
# assume REMOTE_CONN is an interactive socket handle,
# but DISK_FILE is a handle to a regular file.
autoflush REMOTE_CONN 1;                                  # unbuffer for clarity
autoflush DISK_FILE                  0;                   # buffer this for speed


This avoids the bizarre select business, and makes your code much more readable. Unfortunately,
your program takes longer to compile because you're now including the IO::Handle module, so
thousands and thousands of lines must first be read and compiled. Learn to manipulate $| directly, and
you'll be happy.
To ensure that your output gets where you want it, when you want it, buffer flushing is important. It's
particularly important with sockets, pipes, and devices, because you may be trying to do interactive I/O
with these - more so, in fact, because you can't assume line-buffering. Consider the program in Example
7.7.
Example 7.7: getpcomidx

Code:
#!/usr/bin/perl
# getpcomidx - fetch www.perl.com's index.html document
use IO::Socket;
$sock = new IO::Socket::INET (PeerAddr => 'www.perl.com',
                                             PeerPort => 'http(80)');
die "Couldn't create socket: $@" unless $sock;
# the library doesn't support $! setting; it uses $@
$sock->autoflush(1);
# Mac *must* have \015\012\015\012 instead of \n\n here.
# It's a good idea for others, too, as that's the spec,
# but implementations are encouraged to accept "\cJ\cJ" too,
# and as far as we've seen, they do.
$sock->print("GET /index.html http/1.1\n\n");
$document = join('', $sock->getlines());
print "DOC IS: $document\n";


There's no way to control input buffering using any kind of flushing discussed so far. For that, you need
to see Recipes Recipe 15.6 and Recipe 15.8.
See Also
The $| entry in perlvar (1), and in the "Special Variables" section of Chapter 2 of Programming Perl; the
documentation for the standard FileHandle and IO::Handle modules (also in Chapter 7 of Programming
Perl ); the select function in perlfunc (1) and in Chapter 3 of Programming Perl

Quelle: Perl Cookbook

Dieser Post wurde am 21.04.2006 um 21:53 Uhr von Pler editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.04.2006, 23:24 Uhr
kronos
Quotenfisch
(Operator)



Code:
$| = 1;

So einfach ist das Leben.

Aber sag' jetzt nicht, dass du das alles für mich abgetippt hast...?
--
main($)??<-$<='?'>>2?main($-!!putchar(
(("$;99M?GD??(??/x0d??/a:???;a"+'?'/4)
??($??)+'?'/3-2-1+$%2)??''?')):'?';??>
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
22.04.2006, 01:32 Uhr
Pler
Einer von Vielen
(Operator)



Zitat von kronos:

Aber sag' jetzt nicht, dass du das alles für mich abgetippt hast...?


Ja klar, und das alles Fehlerfrei!

Ne Ne, ich hab hier nur einen großen Vorrat an E-Books. Copy+Paste! Wenn ich das nur als Buch gehabt hätte, dann hätte ich mir das mal selber durchgelsen und dann gesagt was du brauchst. So hab ich nur nach dem entsprechenden Kapitel gesucht und das dann hier eingefügt. Lesen musstest du ja selbst.

Passt schon!
Und immerhin weiß ich jetzt auch wieder ein bisschen mehr.

(Oh Gott ich lese grad, was ich da oben in meinem ersten Post zusammengeschieben hab... Nächsten Monat mache ich einen zehn-Fingerkurs)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ Perl/CGI ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: