2011-01-27 1 views
3

私は毎晩同じ時刻に実行する必要のあるスクリプトをPerlで書いていますが、時には時間を変更する必要があることもあります。私はCPANでSchedule::Cronを見つけました。それは私がしたいことをします。スケジューラの起動時にrunメソッドのドキュメントによると、Schedule :: Cronで予定時刻を変更する

nofork => 1

はforkしないでください。代わりに、ジョブは現在のプロセス内で実行されます。実行されたジョブでは、スクリプトのグローバル変数に完全にアクセスできるため、別の時間に実行されている他のジョブに影響を与える可能性があります。

これは私がしたいことですが、実行していません。グローバル変数のメモリ位置を調べるときはいつでも同じですが、タスクの開始時に値は変更されません。

私はこれをWindowsとLinuxの両方で実行しました。私のロジックが正しいかどうかを他の誰かに見てもらいました。グローバル変数への変更を維持するためには何が必要ですか?

use warnings; 
use strict; 

use Schedule::Cron; 
use Time::localtime; 

use constant { 
    EVERY_DAY_10PM => '* * * * * 4,16,28,40,52', 
    EVERY_DAY_NOON => '* * * * * 0,12,24,36,48', 
    EVERY_DAY_2AM => '* * * * * 7,19,31,43,55' 
}; 

############GLOBAL VARIABLES############ 
our $cron = new Schedule::Cron(\&runUpdate); 
our $cronId; 
our $updateTimeDirty = 0; 
############END GLOBAL VARIABLES############ 

############MAIN PROGRAM BODY############ 
$cronId = $cron->add_entry(EVERY_DAY_10PM);#defaults to \&runUpdate 
$cron->add_entry(EVERY_DAY_NOON, \&changeTime); 
$cron->run(no_fork => 1); 
############END MAIN PROGRAM BODY############ 

sub changeTime { 
    our $cron; 
    our $cronId; 
    our $updateTimeDirty; 

    print "updateTimeDirty is $updateTimeDirty\n"; 
    print "udpateTimeDirty location: " . \$updateTimeDirty . "\n"; 
    print "cron object: " . \$cron . "\n"; 

    if ($updateTimeDirty) { 
     my $cronEntry = $cron->get_entry($cronId); 
     $cronEntry->{time} = EVERY_DAY_2AM; 
     $cron->update_entry($cronId, $cronEntry); 
    } 
    print "\n"; 
} 

sub runUpdate { 
    our $updateTimeDirty; 

    $updateTimeDirty = 1; 
    print "Updating at " . localtime()->sec . " ($updateTimeDirty)\n\n"; 
} 

答えて

7

no_forknoforkとの間に有意な違いがあります。試してみてください:

$cron->run(nofork => 1); 
+1

私はドキュメントを引用したときに私の答えも正しく投稿しました。ありがとう。そのアンダースコアはフォークを引き起こしていたので、私は変数のコピーを変更していました。 – treed

+1

良いキャッチ!モジュールのより徹底したオプションチェックのための強力な議論をします。 – toolic

関連する問題