Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Flushing the print buffers.

by kansaschuck (Sexton)
on Feb 21, 2008 at 19:48 UTC ( #669369=perlquestion: print w/ replies, xml ) Need Help??
kansaschuck has asked for the wisdom of the Perl Monks concerning the following question:

I've been loving Perl and coding away. I've got a fairly cool monitoring program now running on my PC with the ActiveState. 5.10 Windows XP.

But after chasing some loop problems I find the issue is that the print buffers aren't clearing. For example a "print" command to notify me that I've entered a 60 second sleep coded just before sleep later appears on the windows command prompt screen after sleep is exited. hmmmm My first fight with Perl. And I was begin to love you as much as PHP :-).

So it's off searching for a good clean way to clear the buffers. Doesn't seem to be a universal way to do it. And why do I have to do it any way?

printsometime "better late than never";

I tried

# print buffers to insure messages go to screen quickly
my $old_fh = select(OUTPUT_HANDLE);
$| = 1;
select($old_fh);

Two things, 1) Don't really understand that code and 2) what the heck it didn't work away way

Also saw the flush(3) code mentioned here by a monk.

advice, pointer, suggestion
p.s. I still love Perl.

Comment on Flushing the print buffers.
Re: Flushing the print buffers.
by tilly (Archbishop) on Feb 21, 2008 at 19:58 UTC
    Read Suffering from Buffering and get back to us on whether you can figure out your problem, and whether you understand buffering issues better.

    (Random hint, you're probably writing to STDOUT, so replace OUTPUT_HANDLE with STDOUT in your snipppet.)

      Yes... almost three years later, your post helped a struggling perl scripter... Just wanted to say thanks for the suffering from buffering! Helped a lot. :-j
Re: Flushing the print buffers.
by FunkyMonk (Canon) on Feb 21, 2008 at 19:58 UTC
    I guess you got a "Name "main::OUTPUT_HANDLE" used only once: possible typo" warning with the code you posted

    Try

    my $old_fh = select(STDOUT); $| = 1; select($old_fh);

    • The first select changes the default output filehandle to STDOUT and returns the current default output filehandle to be saved in $old_fh.
    • $|=1 turns on autoflushing on the current output filehandle
    • select($old_fh) restores the original output filehandle

    Generally, if you just want to turn on autoflushing on STDOUT, a simple $|=1 will do.

      This worked nicely:
      my $old_fh = select(STDOUT); $| = 1; select($old_fh);
      Thanks!
Re: Flushing the print buffers.
by chromatic (Archbishop) on Feb 21, 2008 at 20:19 UTC

    If you run the program from the command line, add a newline (\n) to the end of your print statements. STDOUT uses line buffering when connected to an active terminal.

Re: Flushing the print buffers.
by ikegami (Pope) on Feb 21, 2008 at 20:23 UTC

    Don't really understand that code

    I use the more readable

    use IO::Handle qw( ); # For autoflush OUTPUT_HANDLE->autoflush(1);

    If you want to flush without turning on autoflush,

    use IO::Handle qw( ); # For flush OUTPUT_HANDLE->flush();

    (You only need to load IO::Handle once in your program, not everytime autoflush or flush are called.)

      Is it possible with IO::Handle or otherwise to make printing to terminal fully buffered? And then do the flushing manually with $io->flush when I want the output.

      I once wanted to do this to see if it was a noticeable optimization, but it was not important enough to spend time on. It is still not important but I would like to know anyway if someone happens to know.

        ->autoflush(1) will flush after every print/syswrite/etc.
        ->autoflush(0) will flush on demand (->flush), when the buffer is full (all handles) and when "\n" is encountered (when -t HANDLE only).

        If you want something else, you'll need a tied handle or your own print function.

        Good question.  With older Perls (pre-5.8) you could do

        use IO::Handle '_IOFBF'; my $buf; # set fully buffered, with a buffer size of 1024 bytes STDOUT->setvbuf($buf, _IOFBF, 1024);

        but these days, setvbuf/setbuf are no longer available unless perl is compiled to explicitly not use perlio.

        I'd like to know myself whether there is a substitute for setvbuf (without writing your own XS), as on rare occasions there might be valid uses for being able to control buffering mode or buffer size with Perl. (The function doesn't seem to be POSIX, so use POSIX; wouldn't help, AFAIK...)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://669369]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2014-12-28 06:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (179 votes), past polls