http://www.perlmonks.org?node_id=941869

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

Hi all, I have two function, the first executes a unix command FONCTION1 and the second FONCTION2 write the output of the command in a file. I want to execute the FONCTION1 and the FONCTION2 every 6 seconds, how to do that in the main. Thank's

Replies are listed 'Best First'.
Re: Run code every 6seconde
by moritz (Cardinal) on Dec 05, 2011 at 15:06 UTC
Re: Run code every 6seconde
by vinian (Beadle) on Dec 05, 2011 at 15:45 UTC

    it's easy to do it with POE

    #!/usr/bin/perl # vim: set et sta ts=4 sw=4 sts=4: # vi: set ts=4: # # use strict; use warnings; use POE; POE::Session->create( inline_states => { _start => \&handler_start, fun1 => \&fun1, fun2 => \&fun2, _stop => \&handler_stop, }); POE::Kernel->run(); exit; sub handler_start { my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION]; print "Starting !\n"; $kernel->yield( 'fun1' ); $kernel->yield( 'fun2' ); } sub fun1 { my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION]; print "I'm function 1!\n"; $kernel->delay(fun1 => 6); } sub fun2 { my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION]; print "I'm FUNCTION 2!\n"; $kernel->delay(fun2 => 6); } sub handler_stop { print "Stop !!\n"; }

    Output:

    Starting ! I'm function 1! I'm FUNCTION 2! I'm function 1! I'm FUNCTION 2! I'm function 1! I'm FUNCTION 2! ...

      You call that easy? Holy camel shit, is POE ridiculously verbose. Try this instead:
      #!/usr/bin/perl use 5.010; use strictures; use AnyEvent qw(); my %events; $events{function1} = AE::timer(0, 6, sub { say q(I'm function 1!); }); $events{function2} = AE::timer(0, 6, sub { say q(I'm function 2!); }); $events{main} = AE::cv->recv;
      Whew! This is a great example of why I never used POE. Fortunately, Reflex hides most of… that:
      use 5.010; use Reflex::Interval; my %events; $events{func1} = Reflex::Interval->new(interval => 1, on_tick => sub { say 'I am function 1!' } ); $events{func2} = Reflex::Interval->new(interval => 1, on_tick => sub { say 'I am function 2!' } ); Reflex->run_all;
      Edit: ++ for the AnyEvent example above too.
Re: Run code every 6seconde
by keszler (Priest) on Dec 05, 2011 at 15:10 UTC

    Assuming that FONCTION1 and FONCTION2 will reliably execute in less than 6 seconds, and that exact timing is not critical:

    my $did_this_time = 0; while (1) { my $now = time; if ( $now != $did_this_time && $now % 6 == 0 ) { $did_this_time = $now; FONCTION1(); FONCTION2(); } }

    update: forgot to mention that this will keep the CPU rather busy... Adding a sleep 1; to the loop will help with that.

      If it takes 3 seconds for FONCTION1() to run, and 4 seconds for FONCTION2(), your script waits 5 seconds for the next run. An alternative way would be:
      my $next = time; while (1) { $next = time if $next < time; $next += 6; FONCTION1; FONCTION2; sleep $next - time; }
      This still has all the caveats of using sleep (may sleep longer, may be terminated by a signal, may actually sleep for a second if the argument is 0), but it won't miss its "slot" if a run of FONCTION1(); FONCTION2() takes more than 6 seconds.

      thanks for reply. after 60 second ,i need to close my file using FONCTION3.Can you correct me please or if you have another proposition.

      my $did_this_time = 0; my $i=0; Fonction0; while (1) { my $now = time; if ( $now != $did_this_time && $now % 6 == 0 ) { $did_this_time = $now; $i++; FONCTION1(); FONCTION2(); if (i==10) { FONCTION3(); break; } } }