Perl多个子例程

时间:2014-03-06 08:11:21

标签: perl

对于perl专家来说,这可能是一个简单的问题 -

我正在尝试运行一个逻辑上应该执行此操作的脚本>

Main
{
 While (true)
  Call Sub A
  Call Sub B
  Call Sub C
}

Sub A
{
Go execute a method A for whatever it needs to do ---
before next time method A runs it need to wait atleast 60 seconds but i still want to call method B in these 60 seconds.
}

Sub B
{
  Go execute a method B for whatever it needs to do ---
before next time method b runs it need to wait atleast 60 seconds but i still want to call method C in these 60 seconds in mean time.

}

Sub C
{
  Go execute a method C for whatever it needs to do ---
before next time method C runs it need to wait atleast 60 seconds at this moment control should be back in Main and wait for first 60 seconds of A to expire so that Sub A can be called
}

我的问题: 问:我可以做到最好和最优化的方式 - ?

问:如果我在每个sub中放入60,那么即使60秒到期也不会调用next sub,这将延迟整体处理。

问:我希望按顺序每60秒调用3个潜艇

Q最后如果我需要每60秒调用2个潜水艇并且每小时最后一次潜水 - 我该怎么做?

评论 - 我的想法是将UTC作为一个变量并将其存储在一个变量中并在时间到期时继续检查时间而不是调用单个子,但不确定它是否是运行代码的最佳方式。

4 个答案:

答案 0 :(得分:3)

在子程序内记录上次运行的时间,然后在下次执行时等待:

use feature 'state';

my $sleep_duration = 60; # seconds

sub foo {
   state $last_execution = 0;
   my $remaining = $last_execution + $sleep_duration - time;
   sleep $remaining if $remaining > 0;
   $last_execution = time;

   ...; # normal processing for this sub
}

答案 1 :(得分:1)

你可能想要use threads。以下代码段可能会为您提供一个起点。由于你有四个 Qs 而不是一个,我不会详细介绍它们。

#!/usr/bin/perl

use warnings;
use strict;
use threads;

my @t = (
  threads->create(\&A),
  threads->create(\&B),
  threads->create(\&C)
);

$t[0] -> join();
$t[1] -> join();
$t[2] -> join();

sub A {
  for my $i (1 .. 10) {
     print "A $i\n";
     sleep 60;
  }
}

sub B {
  for my $i (1 .. 20) {
     print "B $i\n";
     sleep 60;
  }
}

sub C {
  for my $i (1 .. 3) {
     print "C $i\n";
     sleep 60;
  }
}

答案 2 :(得分:1)

使用Amon的想法,但在函数外部使用休眠逻辑

sub get_sleeper {

  my ($sleep_duration) = @_;

  my $last_execution = 0;
  return sub {
    my $remaining = $last_execution + $sleep_duration - time();
    sleep $remaining if $remaining >0;
    $last_execution = time();
  };
}

my ($sleepA, $sleepB, $sleepC) = map get_sleeper(60), 1..3;
while (1) {
  $sleepA->(); SubA();
  $sleepB->(); SubB();
  $sleepC->(); SubC();
}

答案 3 :(得分:0)

两个答案都很好但是中间方式是:(从amon的答案中偷走)

use feature 'state';

my $sleep_duration = 60; # seconds

sub foo {
   state $last_execution = 0;
   my $remaining = $last_execution + $sleep_duration - time;
   if ($remaining > 0)
   {
       return "Waiting";  # Make sure main checks for this to know whether the sub ran.
   }

   ...; # normal processing for this sub
}

这将允许您在此等待时运行下一个sub而无需多个线程。但是,当然,这意味着只有在其他两个人有机会之后,这个潜艇才能运行。这意味着你混淆了订单并依赖于潜艇,在下一次通话之前需要60秒以上的时间。