Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
P is for Practical
 
PerlMonks  

create new task from main program

by benlaw (Scribe)
on Apr 11, 2006 at 03:17 UTC ( [id://542468]=perlquestion: print w/replies, xml ) Need Help??

This is an archived low-energy page for bots and other anonmyous visitors. Please sign up if you are a human and want to interact.

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

hi all,

I am writing a program which is check something in while(1) loop, if some condition meet it will run function sub "OTHER" .
however, i want to make it main program keep going on , and the function going on too, moreover, if the condition meet again, create 1 more "OTHER". how can i do that? I try to study POE, but I feel quite difficult to understand ~

thanks!

while(1){ ... ... (Main program) if(condition){ ---> go to create new funtion OTHER{}, Main program keep goi +ng to check, if same condition meet, create 1 more } } ## end of while loop sub OTHER{ }## end of OTHER

Replies are listed 'Best First'.
Re: create new task from main program
by zer (Deacon) on Apr 11, 2006 at 03:41 UTC
Re: create new task from main program
by Zaxo (Archbishop) on Apr 11, 2006 at 03:54 UTC

    You will want to either fork or use threads.pm. Here's how with fork:

    my %kids; my $maxkids = 2; MAIN: while (1) { # . . . delete $kids{+wait} if $maxkids <= keys %kids; if (condition) { defined(my $pid = fork) or warn "kaboom!" and last MAIN; $pid and $kids{$pid}=1 and next MAIN; %kids = (); # child my $result = OTHER(@args); # child # . . . # more child exit 0; # child ends } } delete $kids{+wait} while %kids; sub OTHER { # . . . }
    That is zombie-proofed, but the parent will live, mostly sleeping, until all the kids are done.

    After Compline,
    Zaxo

Re: create new task from main program
by tirwhan (Abbot) on Apr 11, 2006 at 03:58 UTC

    There are many ways you could do this, here is one using the Parallel::ForkManager module:

    use Parallel::ForkManager; use strict; use warnings; my $max = 50 # maximum number of children to create my $pm = new Parallel::ForkManager($max); while(1) { # consider using "while(condition())" here instead # ... if (condition()) { my $pid = $pm->start and next; other(); $pm->finish(); } } sub other { # don't use capitalised subroutine names # ... whatever you want to do in the child }

    Hope this helps


    All dogma is stupid.
Re: create new task from main program
by BrowserUk (Patriarch) on Apr 11, 2006 at 04:16 UTC

    And here's some working threads code to get you started.

    Note:depending upon what you are doing in your sub, and whether you need the results from the subs back in the main program, it could get more complicated than this--but it will at least be doable.

    #! perl -slw use strict; use threads; $|=1; my @threads; for my $i ( 1 .. 10 ) { ## if the condition is true if( $i & 1 ) { ## every odd number matches ## Start a thread to run the sub ## Passing the number as an argument ## And saving the thread object, push @threads, async \&other, $i; } } ## Wait for all the threads to finish $_->join for @threads; ## Done. exit; sub other{ my( $number ) = @_; print "Other( $number ) starting"; ## pretend we're doing something that takes a while... for( 1 .. rand 10 ) { print "Other( $number ) busy ..."; sleep 1; } print "Other( $number ) finished"; } __END__ C:\test>542468 Other( 1 ) starting Other( 1 ) busy ... Other( 3 ) starting Other( 3 ) busy ... Other( 5 ) starting Other( 5 ) busy ... Other( 7 ) starting Other( 7 ) busy ... Other( 9 ) starting Other( 9 ) finished Other( 1 ) busy ... Other( 3 ) finished Other( 5 ) busy ... Other( 7 ) busy ... Other( 1 ) busy ... Other( 5 ) finished Other( 7 ) busy ... Other( 1 ) busy ... Other( 7 ) busy ... Other( 1 ) busy ... Other( 7 ) busy ... Other( 1 ) busy ... Other( 7 ) busy ... Other( 1 ) busy ... Other( 7 ) busy ... Other( 1 ) finished Other( 7 ) busy ... Other( 7 ) finished

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Hi ,
      I try to combined the code with threads,

      but it shows "thread failed to start: Not a CODE reference at D:/Perl/lib/threads.pm" is that any go worse?
      use strict; use Win32::ChangeNotify; use Win32::IPC; use File::Basename; use File::Glob; use DBI; use threads; my $path = 'c:\temp\buffer\event'; #$|=1; my @threads; ### Main program part my $notify = Win32::ChangeNotify->new( $path, 0, 'FILE_NAME' ); my %last;@last{ glob $path . '\*' } = (); CHECK_MAIN(); while( 1 ) { $notify->wait; $notify->reset; my @files = glob $path . '\*'; if(@files == scalar keys %last) { my %temp; @temp{ @files } = (); delete @temp{ keys %last }; foreach my $file (keys %temp){ my $currentFile = basename $file; if ($currentFile =~ /\.log$/){ push @threads, async \&READ_FILE($file); # READ_FILE("$file"); } } } undef %last; @last{ @files } = (); } $_->join for @threads; exit 0; sub CHECK_MAIN{ } sub READ_FILE{ my $file = shift; my $pattern; my $errMsg; open(F, "unix.txt")|| die "unix\.txt not found\nopen : $!"; while(<F>){ chomp($_); $pattern .= $_."|"; } close(F); chop($pattern); my (@errlog, @normal) = (); chomp($file); $file =~ s/\\/\//g; sleep 1; open(TARGET, $file) || die "$file not found\nopen : $!"; while (<TARGET>){ if(/$pattern/ig){ next if(/root\-oracle/ig); chomp($_); my $temp = "$&\|".$_; push (@errlog, $temp); }else{ push (@normal, $_); } } close(TARGET) || warn "close : $!"; # print "@errlog"; #SEND_SMS(\@errlog) if(@errlog > 0); #ADD_DATA(\@errlog) if(@errlog > 0); } # END of READ_FILE

        Changing

        push @threads, async \&READ_FILE($file);

        to

        push @threads, async \&READ_FILE, $file;

        should cure that problem.

        Ie. You need to pass the address of the subroutine, and the parameter as separate items. What you were doing is calling the function and then passing the address of the return value to async

        HTH.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: create new task from main program
by benlaw (Scribe) on Apr 11, 2006 at 05:34 UTC
    Thanks all, these are great!
Re: create new task from main program
by benlaw (Scribe) on Apr 13, 2006 at 03:30 UTC
    Ooop , 1 more problem ,
    I found the program memory grows larger and not free up, i try to use threads->detach() but it seems cannot detach from memory

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://542468]
Approved by Corion
help
Sections?
Information?
Find Nodes?
Leftovers?
    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.