【问题标题】:run, save variable state, interrupt execution, and reload variables from the last state before the interrupt [duplicate]运行,保存变量状态,中断执行,并从中断前的最后一个状态重新加载变量[重复]
【发布时间】:2021-08-13 18:16:09
【问题描述】:

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

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 文件移动到另一个目录(即删除。 txt 从当前目录)。然后我必须能够继续从各个索引到已经打印的行[1 2 3 4 6 7 8 11 12 13 15 16 17] 的交互。

注意:我知道:“要暂停程序,您可以在程序运行时键入 ^ z (= ctrl-z) 1。然后键入 BG 以在后台发送(已停止)进程。要再次恢复,请键入 FG(或 fg,以防您有严重的背景 - 键入 Jobs 以列出它们)。“但这并不是我所期望的。

【问题讨论】:

  • @Dada 谢谢!它似乎与我正在寻找的内容相关并且可以帮助寻找解决方案,但仍然需要能够打印出您停止的索引并手动在代码中重新插入该索引,因为如果我只需关闭执行并在几个小时后返回执行它。

标签: perl compiler-optimization recompile


【解决方案1】:

也许您正在寻找的内容可以通过以下代码 sn-p 实现checkpoint 方法来演示。

代码实现了两个函数来存储/恢复执行stagedata_set

如果代码在执行过程中中断,那么后续的重新运行将在完成stage后通过恢复之前保存的data_set继续启动。

注意:为了演示,将exit 放在store_checkpoint($data) 之后,放在STAGE2 的末尾。运行脚本一次,删除添加的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};
}

【讨论】:

  • 我正在尝试处理如何使用例如$bytes = $data -&gt;{bytes}$bitmask$callback$bytes(在sub powerset 内)的值捕获到checkpoint.dat 中.但我还需要知道如何运行sub powerset 多次,但我仍然没有弄清楚如何做到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-14
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
  • 1970-01-01
  • 2020-03-06
相关资源
最近更新 更多