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

perl – 为什么system()返回0,即使它执行的程序死掉

发布时间:2020-12-15 23:22:40 所属栏目:大数据 来源:网络整理
导读:我正在尝试测试一段代码($code),以确保一次只运行一个程序实例: #!/usr/bin/perl# test_lockuse strict;use warnings;( my $code = 'CODE') =~ s/^s+//gm; #!/usr/bin/perl use strict; use warnings; use Fcntl qw(:flock); # Make sure only one instanc
我正在尝试测试一段代码($code),以确保一次只运行一个程序实例:

#!/usr/bin/perl
# test_lock
use strict;
use warnings;

( my $code = <<'CODE') =~ s/^s+//gm;
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Fcntl qw(:flock);

    # Make sure only one instance of the program is running at a time.
    open our $Lock,'<',$0 or die "Can't lock myself $0: $!";
    flock $Lock,LOCK_EX | LOCK_NB
      or die "Another instance of $0 is already running. Exiting ...n";

    sleep(2);
CODE

my $progfile = '/tmp/x';
open my $fh,'>',$progfile or die $!;
print $fh $code;
close $fh;

$|++;
my $ex1 = system("perl $progfile &");
print "First system(): $ex1n";
my $ex2 = system("perl $progfile");
print "Second system(): $ex2n";

我期望第二次调用system()会返回一个非零值($ex2),因为它无法获得锁定并死掉.但是我得到:

$perl test_lock
First system(): 0
Another instance of /tmp/x is already running. Exiting ...
Second system(): 0

我的假设有什么问题? (有没有更好的方法来测试$代码?)

解决方法

我想这可能是因为你有竞争条件.你怎么知道这个错误实际上来自你的第二个过程?

因为,例如,运行:

perl /tmp/x & perl /tmp/x ; echo $?

您可能获得零回报,因为竞赛的“赢家”可能是后一个过程(返回您正在捕获的代码). (尝试几次,你会看到不同的结果)

你也确实有两个命令在shell之间做了一些细微的差别 – 来自docs:

If there is only one scalar argument,the argument is checked for shell metacharacters,and if there are any,the entire argument is passed to the system’s command shell for parsing (this is /bin/sh -c on Unix platforms,but varies on other platforms). If there are no shell metacharacters in the argument,it is split into words and passed directly to execvp,which is more efficient.

所以实际上你应该在你的第一个perl之前看到sh的调用,这意味着它实际上更有可能需要更长的时间才能到达锁定点.

这意味着你的命令更像是:

sh -c "perl /tmp/x"& perl /tmp/x; echo $?

运行几次,看看你获得非零错误代码的次数.这通常并不常见,因为通常shell启动的“延迟”足以确保第二个实例在大多数时间赢得比赛!

如果你有linux – 尝试strace -fTt yourscript,它将跟踪执行流程.或者你可以在运行时明智地使用$$来报告进程pid.

(编辑:李大同)

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

    推荐文章
      热点阅读