Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

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
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2017-07-23 21:12 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (347 votes). Check out past polls.