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

Re^3: Need sleep walking help

by Todd Chester (Scribe)
on Feb 01, 2017 at 08:31 UTC ( [id://1180742]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Need sleep walking help
in thread Need sleep walking help

Oops, got it.  I just have to add:

# set up flushing select(STDERR); $| = 1; select(STDOUT); # default $| = 1;
to the top of my program.

Reference: https://blog.famzah.net/2010/04/08/auto-flush-both-stdout-and-stderr-in-perl/

Chuckle: I though "|" was a font variation of "I". Didn't realize it was a pipe sign. That is why I didn't understand the paper

Thank you!
-T

Replies are listed 'Best First'.
Re^4: Need sleep walking help
by Discipulus (Canon) on Feb 01, 2017 at 08:51 UTC
    I don't see the need to use that select calls.

    Infact you are not using STDERR at all and in the case of a use of warn a newline is added anyway. From the docs:

    Prints the value of LIST to STDERR. If the last element of LIST does n +ot end in a newline, it appends the same file/line number text as die + does.

    In case of need of a granular control over buffer behaviour you can use the autoflush method from IO::Handle that is the base class for all other IO handle classes.

    In your example you just need to put $|++; after use strict; use warnings; lines.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re^4: Need sleep walking help
by Marshall (Canon) on Feb 02, 2017 at 04:22 UTC
    No, that is not correct.
    STDERR is "unbuffered" by default.
    STDOUT is buffered by default and is the currently selected output file handle by default. You do not need the "select" in this case.

    This should work fine...

    #!/usr/bin/perl use strict; use warnings; $|=1; # turns off stdout buffering mysleep(10); sub mysleep { my $seconds = shift; print "Sleeping for $seconds seconds ... "; for my $second (1..$seconds) { sleep(1); print " $second"; } print " done!\n"; }
    I would not use "Sleep" as the subroutine name. Lower case "sleep" is the library's function name. This kind of upper vs lower case thing can lead to big and confusing troubles! I used "mysleep" instead of "Sleep".

    PS: Something is very odd about your <code>...</code> tags. Do not enclose the <code>...</code> tags inside of something else.

      Where do you get that information?

      $ perl -e "print int STDERR->autoflush for 1..2 " 01 $ perl -e "print int STDOUT->autoflush for 1..2 " 01

      0 means both STDERR and STDOUT were buffered , ie the default is they are buffered

        Hi,

        0 means both STDERR and STDOUT were buffered

        No, that's not correct, it simply reflects the state of the "autoflush" setting. From $|:

        Default is 0 (regardless of whether the channel is really buffered by the system or not; $| tells you only whether you've asked Perl explicitly to flush after each write).
        ie the default is they are buffered

        The issue here is not whether they are buffered, as they always are in one form or another, but the issue is when that buffer is flushed. According to Suffering from Buffering:

        When a filehandle is attached to the terminal, ... it is in line buffered mode by default. A filehandle in line buffered mode has two special properties: It's flushed automatically whenever you print a newline character to it, and it's flushed automatically whenever you read from the terminal. ... But now let's try it with STDOUT attached to a file instead of to the terminal... it isn't line-buffered; only filehandles attached to the terminal are line-buffered by default. ... The filehandle STDERR, which is normally used for error logging, is always in line buffered mode by default.

        And the autoflush setting

        forces a flush right away and after every write or print on the currently selected output channel.

        So STDERR is always in line-buffered mode by default, and Perl decides whether STDOUT should be line-buffered or not depending on whether it's attached to a terminal or not.

        Regards,
        -- Hauke D

        No, I don't think so. I am not sure what your code has to do with anything. If you flush STDOUT after every write, that is same as un-buffering it.

        Consider Program 1:

        #!/usr/bin/perl use warnings; for my $i (1..5) { $x+1; # here just to throw an error to STDERR print "$i\n"; } __END__ Useless use of addition (+) in void context at C:\Projects_Perl\testin +g\demoStdErrorTiming1.pl line 6. Name "main::x" used only once: possible typo at C:\Projects_Perl\testi +ng\demoStdErrorTiming1.pl line 6. Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming1.pl line 6. Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming1.pl line 6. Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming1.pl line 6. Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming1.pl line 6. Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming1.pl line 6. 1 2 3 4 5
        Consider Program 2:
        #!/usr/bin/perl use warnings; $|=1; ### BIG DEAL HERE ### Unbuffers STDOUT for my $i (1..5) { $x+1; #here just to throw an error to STDERR print "$i\n"; } __END__ Useless use of addition (+) in void context at C:\Projects_Perl\testin +g\demoStdErrorTiming2.pl line 7. Name "main::x" used only once: possible typo at C:\Projects_Perl\testi +ng\demoStdErrorTiming2.pl line 7. Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming2.pl line 7. 1 Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming2.pl line 7. 2 Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming2.pl line 7. 3 Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming2.pl line 7. 4 Use of uninitialized value $x in addition (+) at C:\Projects_Perl\test +ing\demoStdErrorTiming2.pl line 7. 5
        Program 1's error messages come out right way while stdout messages come later because the stdout's filehandle's output buffer is not ready to be "flushed", "printed".

        Program 2's error messages are interleaved with "normal" prints because the normal prints are being prematurely flushed out. There is a big,(can be HUGE) performance penalty for this but, this makes debugging easier.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1180742]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-04-20 11:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found