运行,保存变量状态,中断执行,从中断前的最后一个状态重新加载变量

run, save variable state, interrupt execution, and reload variables from the last state before the interrupt

我正在研究一种中断下面 Perl 脚本执行的方法,这样我可以保存交互的时间点,并且我可以 运行 下次从该交互开始。 基本上我看到其他人说“将 Perl 的执行保存在它所在的状态”。 我正在查看脚本内部并试图了解如何提取交互编号并打印到文件中,然后重新插入脚本中作为下一个起始 运行ning.

的初始索引
use strict;
use warnings;
sub powerset(&@) {
    my $callback = shift;
    my $bitmask = '';
    my $bytes = @_/8;
    {
       my @indices = grep vec($bitmask, $_, 1), 0..$#_;
       $callback->( @_[@indices] );
       ++vec($bitmask, $_, 8) and last for 0 .. $bytes;
       redo if @indices != @_;
    }
}
 
powerset { print "[@_]\n" } 1..5;
my $i = 0;

例如:假设我想要一组 1..50 的幂集,然后在我中断执行时,输出上打印的最后一行是 [1 2 3 4 6 7 8 11 12 13 15 16 17]。然后在脚本执行的第二次启动时,我只想将各自的索引迭代到打印的 [1 2 3 4 6 7 8 11 12 13 15 16 17] 行,我不想重做已经在第一个打印结果的迭代 运行 的 Perl 文件。

我的目标是能够启动 file.pl 的第一个 运行,然后在 out.txt 文件 perl file.pl > out.txt 中打印输出,然后移动out.txt 文件到另一个目录(即从当前目录删除 out.txt)。然后我必须能够继续从相应索引到已经打印的 [1 2 3 4 6 7 8 11 12 13 15 16 17] 行的交互。

注意:我知道:“要暂停程序,您可以在程序 运行ning 时键入 ^ z (= ctrl-z) 1。然后键入 BG TO SEND后台的(已停止)进程。要再次恢复它,请键入 FG(如果你有严重的背景,则键入 fg - 键入 Jobs 以列出它们)。”但这并不完全符合我的预期。

也许您正在寻找的东西可以通过以下实现 checkpoint 方法的代码片段来证明。

代码实现了两个函数store/restore执行stagedata_set.

如果代码在执行过程中被打断,那么接下来的运行会在完成stage之后通过恢复之前保存的data_set.[=20=继续执行]

注意:为了演示,在 STAGE2 末尾的 store_checkpoint($data) 之后放置 exit。 运行 脚本一次,删除添加的 exit 并再次重新 运行 脚本。

use strict;
use warnings;
use feature 'say';

use YAML;
use Data::Dumper;

my $checkpoint = 'checkpoint.dat';
my $data;

restore_checkpoint() if -e $checkpoint;

STAGE1:
$data->{data_set} = [ title => 'scientist', age => 27, address => '123 street, NY 12345 USA' ];
$data->{next_stage} = 'STAGE2';
store_checkpoint($data);

STAGE2:
$data->{data_set} = [ title => 'professor', age => 45, address => '234 street, WA 98230 USA' ];
$data->{next_stage} = 'STAGE3';
store_checkpoint($data);

STAGE3:
$data->{data_set} = [ title => 'doctor', age => 53, address => '345 street, OK 56789 USA' ];
$data->{next_stage} = 'STAGE4';
store_checkpoint($data);

STAGE4:
$data->{data_set} = [ title => 'CEO', age => 38, address => '456 street, MA 54321 USA' ];
$data->{next_stage} = 'STAGE5';
store_checkpoint($data);

STAGE5:
say 'Done';


sub store_checkpoint {
    my $data = shift;
    say 'INFO: save_checkpoint ' . $data->{next_stage};
    
    open my $fh, '>', $checkpoint
        or die "Couldn't open $checkpoint";
        
    say $fh Dump($data);
        
    close $fh;
}

sub restore_checkpoint {

    say 'INFO: restore_checkpoint';
    
    open my $fh, '<', $checkpoint
        or die "Couldn't open $checkpoint";
        
    my $yaml = do { local $/; <$fh> };
    
    close $fh;
    
    $data = Load($yaml);
    say Dumper($data);
    
    say 'INFO: continue stage ' . $data->{next_stage};
    
    goto $data->{next_stage};
}