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
Re: create new task from main program
by zer (Deacon) on Apr 11, 2006 at 03:41 UTC
|
| [reply] |
Re: create new task from main program
by Zaxo (Archbishop) on Apr 11, 2006 at 03:54 UTC
|
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.
| [reply] [d/l] |
Re: create new task from main program
by tirwhan (Abbot) on Apr 11, 2006 at 03:58 UTC
|
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
| [reply] [d/l] |
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.
| [reply] [d/l] |
|
|
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
| [reply] [d/l] |
|
|
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.
| [reply] [d/l] [select] |
|
|
|
|
|
|
Re: create new task from main program
by benlaw (Scribe) on Apr 11, 2006 at 05:34 UTC
|
Thanks all, these are great! | [reply] |
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 | [reply] |
|
|