> Papo Napolitano wrote:
>
> >> On Feb 18, 2004, at 4:45 PM, Papo Napolitano wrote:
> >>
> >> > Heh, sorry... I simplified the code...
> >> > I'm still not posting the full source because it's like 15 files :(
> >> >
> >> >
> >> > while (1) {
> >> >   Fork("Whatever");
> >> >   sleep 60;
> >> > }
> >>
> >> The first time you showed this loop, it had multiple fork()s in it.
> >> Now it's just one.  Which is it.
> >>
> >> > sub Fork {
> >> >   my $module = shift;
> >> >   my @params = @_;
> >> >   my $pid = fork;
> >> >   return $pid if $pid;
> >> >   $module->Run(@params);
> >> >   exit;
> >> > }
> >>
>
> [snip]
>
> >
> > I'm changing the code to try to make it work... Right now I'm using:
> >
> > for ('test1', 'test2', 'test3') {
> >   print STDERR scalar(localtime) . " - fork $_\n";
> >   Fork("TestModule", $_);
> >   print STDERR scalar(localtime) . " - enter sleep\n";
> >   sleep 60;
> >   print STDERR scalar(localtime) . " - exit sleep\n";
> > }
> >
> > And in TestModule.pm:
> >
> > package TestModule;
> > sub Run {
> >   my $self = shift;
> >   my $param = shift;
> >   print STDERR scalar(localtime) . " - $self: $param\n";
> > }
> >
> > Output is this:
> >
> > Wed Feb 18 20:37:04 2004 - fork test1
> > Wed Feb 18 20:37:04 2004 - enter sleep
> > Wed Feb 18 20:37:04 2004 - TestModule: test1
> > Wed Feb 18 20:37:04 2004 - exit sleep
> > Wed Feb 18 20:37:04 2004 - fork test2
> > Wed Feb 18 20:37:04 2004 - enter sleep
> > Wed Feb 18 20:37:04 2004 - TestModule: test2
> > Wed Feb 18 20:37:04 2004 - exit sleep
> > Wed Feb 18 20:37:04 2004 - fork test3
> > Wed Feb 18 20:37:04 2004 - enter sleep
> > Wed Feb 18 20:37:04 2004 - TestModule: test3
> > Wed Feb 18 20:37:04 2004 - exit sleep
> > Wed Feb 18 20:37:04 2004 - fork test1
> > Wed Feb 18 20:37:04 2004 - enter sleep
> > Wed Feb 18 20:37:04 2004 - TestModule: test1
> > Wed Feb 18 20:37:04 2004 - exit sleep
> > Wed Feb 18 20:37:04 2004 - fork test2
> > Wed Feb 18 20:37:04 2004 - enter sleep
> > Wed Feb 18 20:37:04 2004 - TestModule: test2
> > Wed Feb 18 20:37:04 2004 - exit sleep
> > Wed Feb 18 20:37:04 2004 - fork test3
> > Wed Feb 18 20:37:04 2004 - enter sleep
> > Wed Feb 18 20:37:04 2004 - TestModule: test3
> > Wed Feb 18 20:37:04 2004 - exit sleep
>
> sleep is interruptable (ie, signals can wake it up) and that's why it's
> popular for busy wait in a loop. the following demonstrates this side
> affect:
>
> #!/usr/bin/perl -w
> use strict;
>
> my $stop = 0;
>
> $SIG{CHLD} = sub{wait; $stop = 1};
>
> my $p = fork;
>
> if($p){
>         while(!$stop){
>                 print 5 - sleep(5)," seconds left to be sleep ($$)\n";
>         }
> }else{
>         sleep(14);
>         exit;
> }
>
> __END__
>
> prints:
>
> 0 seconds left to be sleep (7632)
> 0 seconds left to be sleep (7632)
> 1 seconds left to be sleep (7632)
>
> the first line means the parent slept 5 full seconds
> the second line also means the parent slept 5 full seconds
> the third line shows the parent only slept 4 (5-4=1) seconds
>
> do a little math gives us: 5 + 5 + 4 = 14 which is exactly the time
> the child finished and wake up the parent.
>
> there is no general solution to stop sleep from wake up by a signal
although
> most *nix os support something called an uninterrupted sleep which a
system
> call is make to put the process to sleep and only another special system
> call can wake it up. you need to code this in C so i will not show you the
> example in this Perl list.
>
> having said that, there is a not so perfect solution which simply cache
> whatever sleep return and sleep more. for example, the following makes
sure
> you sleep at least full 7 seconds:
>
> #!/usr/bin/perl -w
> use strict;
>
> $SIG{CHLD} = sub{wait};
>
> if(fork){
>         print scalar localtime,"\n";
>         real_sleep(7);
>         print scalar localtime,"\n";
> }else{
>         sleep(3);
>         exit;
> }
>
> sub real_sleep{
>         my $s = shift;
>         my $t = 0;
>         while(1){
>                 my $i = sleep($s);
>                 unless($i){
>                         return;
>                 }else{
>                         $s -= $i;
>                 }
>                 print "$s more seconds to sleep\n";
>         }
> }
>
> __END__
>
> prints:
>
> Thu Feb 19 10:36:45 2004
> 4 more seconds to sleep
> 0 more seconds to sleep
> Thu Feb 19 10:36:52 2004
>
> the second line is caused by the exiting of the child process which died
> after 3 seconds (4 + 3 = 7). unlike the previous version the child did not
> affect our parent process and we slept full 7 seconds. this work even you
> have multiple children. you probably need to do something similiar in your
> script to make sure you sleep enough seconds.
>
> as a final note, the above code is "correct" only in terms of algr. and
how
> the sleep function is suppose to work. external factors such as machine
> load, cpu demands, etc can cause the machine to be not able to wake up at
> the precise moment so you must account for that.
>
> david

David,

That was the kind of explanation I was looking for.
Anyway, I've found a module Scheduler::Cron that does exactly what I need.
The golden rule: Look first in cpan.

Thanks you all!


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to