in reply to Re^5: Please suggest a non-forking way to do this (OS: windows)
in thread Please suggest a non-forking way to do this (OS: windows)

that would block. And as far as I know

A timer calling sysread at a fast interval will not block.... the <> operator might. Sysread will try to read the pipe every 10 ms (or so), and if nothing is there, will just let the timer go on to the next round. Tk will remain responsive.

I think its easier for people to switch to linux, than to figure out hacks to make win32 work. :-)


I'm not really a human, but I play one on earth Remember How Lucky You Are
  • Comment on Re^6: Please suggest a non-forking way to do this (OS: windows)

Replies are listed 'Best First'.
Re^7: Please suggest a non-forking way to do this (OS: windows)
by ikegami (Patriarch) on Sep 29, 2008 at 20:38 UTC

    A timer calling sysread at a fast interval will not block

    Why do you say sysread won't block?

    than to figure out hacks to make win32 work. :-)

    Win32 works fine. It's fighting Perl on Win32 that requires effort.

      Why do you say sysread won't block?

      This script does it, by adding the O_NONBLOCK flag to the piped open. top is set to give output every 10 secs, yet the Tk gui is still running fine.

      #!/usr/bin/perl use warnings; use strict; use Tk; my $mw = MainWindow->new(-background => 'gray50'); my $text = $mw->Scrolled('Text')->pack(); my $pid; my $startb = $mw->Button( -text => 'Start', -command=> \&work, )->pack(); my $count = 0; my $label = $mw->Label(-textvariable=>\$count)->pack(); my $testtimer = $mw->repeat(500, sub { $count++} ); my $stopb = $mw->Button( -text => 'Exit', -command=>sub{ kill 9,$pid; exit; }, )->pack(); MainLoop; ##################################### sub work{ $startb->configure(-state=>'disabled'); use Fcntl; #long 10 second delay between outputs $pid = open (my $fh, "top -b -d 10 |" ) or warn "$!\n"; fcntl($fh, F_SETFL, O_NONBLOCK) || die "$!\n"; # Set the non-block flags my $repeater; $repeater = $mw->repeat(10, sub { if(my $bytes = sysread( $fh, my $buf, 1024)){; $text->insert('end',$buf); $text->see('end'); } } ); }

      I'm not really a human, but I play one on earth Remember How Lucky You Are

        Not quite.

        use strict; use warnings; use Fcntl qw( F_SETFL O_NONBLOCK ); my $fh = \*STDIN; fcntl($fh, F_SETFL, O_NONBLOCK) || die "$!\n"; sysread($fh, my $buf, 1);
        Your vendor has not defined Fcntl macro F_SETFL, used at ...

        Similarly, $fh->blocking(0); is a no-op.

        Like I said earlier, as far as I know, it's impossible to detect whether the pipe has data waiting.