加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

在Perl中,为什么“在BEGIN里面岔开……一个可怕的前景”?

发布时间:2020-12-15 21:47:09 所属栏目:大数据 来源:网络整理
导读:作为对另一个SO Q A的评论的一部分,用户注意到: fork inside BEGIN is a horrible prospect 为什么这是一个“可怕的前景”? (在技术层面 – 让我们放弃设计的可读性或美观) use strict;BEGIN { # Begin block to fork off a child process. # This is done
作为对另一个SO Q& A的评论的一部分,用户注意到:

fork inside BEGIN is a horrible prospect

为什么这是一个“可怕的前景”? (在技术层面 – 让我们放弃设计的可读性或美观)

use strict;
BEGIN {
    # Begin block to fork off a child process.
    # This is done in BEGIN,because otherwise My::HeavyModule module
    # will be loaded BEFORE the fork and thus inherited by child process
    # which is something we want to avoid

    my $init = 1; # Some lightweight init code

    if (my $pid = fork()) {
        # Nothing to do here,proceed to the rest of the main program
    } else {
        die "cannot fork" unless defined $pid;
        print "Child process started!n";
        exit 0;
    }
} # End BEGIN block

use My::HeavyModule; # Very heavyweight on both startup time and memory 

# Start parent process logic using My::HeavyModule;

需要明确的是:我不是在问是否有更好的方法来实现此代码的功能.我问为什么这种方法被称为“可怕”,而不是它是否可以被更好的东西取代.

解决方法

我写了以下你所指的评论:

fork inside BEGIN is a horrible prospect. You could also delay compilation for some parts using eval "string" or require,but that also has its issues.

虽然不是因为技术原因(没有超出dan1111 mentioned和explicit portability warning in perlfork),但因为它完全打破了我对任何程序行为的期望.

>每段代码都有一个编译时间.我希望在这里设置包和类,也许会发生一些元编程.
>然后,有一个运行时间,在此期间我们的程序的主要控制流程发生,在此期间正在执行该程序的工作.

Perl使这个简单的区别变得复杂,因为一个块的编译时间是另一个块的运行时间(例如,通过BEGIN或使用或eval或require).但总有一个明确的参考点:0美元的阶段,该程序最初被调用(另见${^GLOBAL_PHASE}).在主脚本的编译时间内总会出现做一些时髦的事情的好主意,但这并不是必须这样做才是最好的做法 – 相反,因此我反对这样做会这样做一个“可怕的前景”.

如果你的程序的主要工作是启动另外两个独立的程序,它可能看起来像这样:

use strict;
use warnings;

my $pid = fork;
if (not defined $pid) {
    die "welp,can't fork: $!";
}
if ($pid) {
    exec $^X,"heavy_program_you_intended_to_be.pl",@ARGV;
}
else {
    ... # background yourself,etc.
    exec $^X,"light_program_you_intended_to_kick_off.pl";
}

但它不会在BEGIN中分叉.我认为这是你可以用Perl做一些事情的众多例子之一,但这并不意味着你应该这样做.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读