Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Troubles with do...while loop and sleep

by imlepid (Acolyte)
on May 26, 2008 at 04:07 UTC ( #688477=perlquestion: print w/replies, xml ) Need Help??
imlepid has asked for the wisdom of the Perl Monks concerning the following question:

I just started working in Perl the other day and it's been going pretty well but today I hit a hitch I can't seem to overcome. I was creating a do...while loop (this also occurs in a simple while loop) with an embedded sleep statement and it was giving me some strange behavior. Finally, I narrowed down to this:
do { sleep(5); printf "Hello...\n"; } while(1);
it outputs "Hello..." at 5 second intervals. where as this:
do { sleep(5); print "Hello..."; } while(1);
displays nothing and just hangs until I hit C-c. Why will the first one display "Hello..." while the second without "\n" not? It must have to do with sleep because if I remove it both will be displayed ad infinitum.
Thanks much for your help in advance.

Replies are listed 'Best First'.
Re: Troubles with do...while loop and sleep
by ikegami (Pope) on May 26, 2008 at 05:14 UTC
    You are suffering from buffering. Here are two fixes:
    use IO::Handle qw( ); STDOUT->autoflush(1); do { sleep(5); print "Hello..."; } while(1);
    use IO::Handle qw( ); do { STDOUT->flush(); sleep(5); print "Hello..."; } while(1);
Re: Troubles with do...while loop and sleep
by runrig (Abbot) on May 26, 2008 at 04:10 UTC
    Add a "\n" to the second one and it should display just as often. Without a linefeed, you're just filling up the buffer (which should get flushed and display when it gets full). Or you can set $| (i.e. $OUTPUT_AUTOFLUSH...see perlvar) to a true value.
Re: Troubles with do...while loop and sleep (line- vs. block-buffered)
by almut (Canon) on May 26, 2008 at 05:39 UTC

    Essentially, there are three buffering modes to be aware of:

    • unbuffered
    • line-buffered
    • block-buffered

    "line-buffered" is typically used with interactive things such as an interactive shell / terminal that your command line runs in.  "block-buffered" is the default, used with almost everything else. And "unbuffered" is only used for special purposes, if you explicitly request that the performance optimisation not be used.  Line-buffered output is flushed when encountering a newline in the stream, while block-buffered output is flushed when the block has filled up.

    Put differently, if you for example redirect the output (an operation which is considered non-interactive) of your snippet which does output the "\n" to a file

    $ >suffbuf

    and then try "tail -f suffbuf" (from another terminal) in an attempt to watch the lines being output, it wouldn't work either... (while it would with $|=1;).  I.e., before you get any output, you'd have to wait quite a while until the buffer has been filled up (typically several kByte), at which moment the whole buffer would be output at once as one block...

Re: Troubles with do...while loop and sleep
by ABuiteman (Initiate) on May 27, 2008 at 14:17 UTC
    It probably has something todo with buffering of your output. And you have to use print "Hello...\n"; Otherwise no newline will not be printed and no buffer flush will occur.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://688477]
Approved by GrandFather
Front-paged by runrig
[Eily]: here
[Eily]: still not xD there
[hippo]: See also Getting Started with Perl for some gentle introductory tutorials.

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2018-02-21 09:54 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (276 votes). Check out past polls.