Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Threads or no Threads

by Anonymous Monk
on Feb 24, 2007 at 05:31 UTC ( [id://601851]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I am trying to get the result of a shell command while using threads but what else is new - I am not having any luck. Some of my commands take a long time so I like to stop them and report the event. Is there a better way to do this using another technique?
use Thread qw(yield async); async { my $time = 10; while ($time--){$command = `shell command`;} yield; }; #do something with command
Thank you.

Replies are listed 'Best First'.
Re: Threads or no Threads (total timeout)
by ikegami (Patriarch) on Feb 24, 2007 at 06:43 UTC

    Or maybe you want to prevent the child from running longer than a certain amount of time.

    use strict; use warnings; use IO::Select qw( ); use IPC::Open2 qw( open2 ); use Time::HiRes qw( time ); # Optional my $timeout = 30.000; # Abort after this many seconds. my $command = '...'; # The command to execute. my $from_child = ''; # Receives the output of the command. my $pid = open2(undef, my $fh_from_child, $command); my $sel = IO::Select->new($fh_from_child); my $abort_time = time + $timeout; for (;;) { my $time_left = $abort_time - time; my @r = $time_left > 0 ? $sel->can_read($time_left): (); if (!@r) { kill(TERM => $pid); die("Child took more than $timeout seconds.\n"); } read($fh_from_child, $from_child, 4096, length($from_child)) or last; } print($from_child); waitpid($pid, 0);

    Also tested. Also won't work on Windows.

    Update: Added call to kill. Could still use some work there.

    Update: Or maybe you want to give a notice at a fixed interval? It should be easy to combine the techniques used in each of my posts to do this.

Re: Threads or no Threads (idle timeout)
by ikegami (Patriarch) on Feb 24, 2007 at 06:27 UTC

    I'm not sure what you want. Are you looking to be notifie when the child has been idle for a certain amount of time?

    use strict; use warnings; use IO::Select qw( ); my $timeout = 30.000; # Notify user after idle for this many secs my $command = '...'; # The command to execute. my $from_child = ''; # Receives the output of the command. open(my $fh_from_child, "$command |") or die("Unable to launch $command: $!\n"); my $sel = IO::Select->new($fh_from_child); for (;;) { my @r = $sel->can_read($timeout); if (!@r) { print("Another $timeout seconds has gone by...\n"); redo; } read($fh_from_child, $from_child, 4096, length($from_child)) or last; } print($from_child);

    Tested on FreeBSD. It won't work on Windows (since you can't select pipes).

Re: Threads or no Threads
by BrowserUk (Patriarch) on Feb 24, 2007 at 09:42 UTC

    Here's a rather simple solution that may work for you.

    #! perl -slw use strict; our $WAIT ||= 10; my $cmd = 'perl -e"$|++;sleep 1, print for 1 .. 10" |'; my $pid = open my $cmdFh, $cmd or die "Couldn't run '$cmd': $!"; sleep 1 while kill 0, $pid and $WAIT--; kill 3, $pid and warn 'Command timed out' if $WAIT; my $results = do{ local $/; <$cmdFh> }; print "Got: '$results'";

    A few simple tests

    c:\test>junk9 -WAIT=2 Command timed out at c:\test\junk9.pl line 11. Got: '12' c:\test>junk9 -WAIT=9 Command timed out at c:\test\junk9.pl line 11. Got: '12345678' c:\test>junk9 -WAIT=10 Got: '12345678910' c:\test>junk9 -WAIT=11 Got: '12345678910'

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Threads or no Threads (Threading, Forking, Signals, Event Loop and Concurrency References)
by eyepopslikeamosquito (Archbishop) on Feb 24, 2007 at 09:12 UTC
Re: Threads or no Threads
by bsdz (Friar) on Feb 24, 2007 at 13:19 UTC
    If you are using Windows, you may want to consider using Win32::Job.
Re: Threads or no Threads
by Anonymous Monk on Feb 24, 2007 at 16:55 UTC
    Thank you guys for your replies. I am actually testing this on Windows but will be using it on Linux. This thread has been very educational. I appreciate it.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-25 22:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found