Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux daemonized MCE进程的状态会影响父进程_Linux_Perl_Parallel Processing - Fatal编程技术网

Linux daemonized MCE进程的状态会影响父进程

Linux daemonized MCE进程的状态会影响父进程,linux,perl,parallel-processing,Linux,Perl,Parallel Processing,我正在使用MCE做一些事情,它一直运行良好。我需要观察事件的发生,然后派生一个MCE进程来处理该事件。这很好,但是我遇到了一个问题,当我认为只有子MCE进程应该受到影响时,子进程中的错误会终止父进程。下面是一个演示此行为的简短程序 #!/usr/bin/perl use strict; use warnings; use MCE::Loop; use MCE::Signal '-setpgrp'; use POSIX "setsid"; $SIG{CHLD} = 'IGNORE'; my

我正在使用MCE做一些事情,它一直运行良好。我需要观察事件的发生,然后派生一个MCE进程来处理该事件。这很好,但是我遇到了一个问题,当我认为只有子MCE进程应该受到影响时,子进程中的错误会终止父进程。下面是一个演示此行为的简短程序

#!/usr/bin/perl

use strict;
use warnings;

use MCE::Loop;
use MCE::Signal '-setpgrp';
use POSIX "setsid";

$SIG{CHLD} = 'IGNORE';

my $mce_maxWorkers = 2;
my $mce_chunkSize = 1;
my @pids;
my $i = 0;

my $name = shift;

while ($i < 2) {
    my $pid = fork();

    if (!defined $pid) {
        print "Can't fork: $!\n";
    }

    elsif ($pid == 0) {

        #setpgrp(0,0);
        (setsid() != -1) || die "Can't start a new session: $!";

        MCE::Loop::init {
            max_workers => $mce_maxWorkers,
            chunk_size => $mce_chunkSize,
            on_post_exit => sub {
                my ($mce, $e) = @_;
                print "$e->{wid}: $e->{pid}: status $e->{status}: $e->{msg}\n";
            }
        };

        my $tail = 'tail -q -f '.$name;
        open my $tail_fh, "-|", $tail or die "Can't open tail\n";

        mce_loop_f {
            my ($mce, $chunk_ref, $chunk_id) = @_;
            my $line = ${$chunk_ref}[0];
            chomp($line);
            print $line."\n";

        } $tail_fh;
        close $tail_fh;

        MCE->shutdown;
        exit;
    }

    else {
        print $pid."\n";
        $i++;
        push(@pids,$pid);
    }
}

foreach my $p (@pids) {
    waitpid $p, 0;
}
如果我向上面的29002发送一个SIGTERM,我希望该进程将与29004、29006和29007一起消失。我还希望过程29001和29003不会受到影响

然而,我看到的是29001和29002一起死亡,而29003仍然存在。在终端上观察到以下错误

shell $ ./monitor1_test.pl tmp/monitor1/test1.log 
29002
29003
test1234
test1234

## monitor1_test.pl: caught signal (INT), exiting

Killed
shell $ MCE::shutdown: method cannot be called while running at /usr/share/perl5/site_perl/MCE/Signal.pm line 371.
END failed--call queue aborted at ./monitor1_test.pl line 371, <$tail_fh> line 1.
shell$./monitor1\u test.pl tmp/monitor1/test1.log
29002
29003
测试1234
测试1234
##监视器1_test.pl:捕获信号(INT),正在退出
被杀死的
shell$MCE::shutdown:在/usr/share/perl5/site_perl/MCE/Signal.pm第371行运行时无法调用方法。
结束失败--调用队列在./monitor1_test.pl第371行第1行中止。
为什么其中一个子进程的终止会以这种方式影响父进程?我是做错了什么,还是错误地认为父母应该经历这一切?我现在有点烦,所以任何建议都将不胜感激

平台:Linux 4.0.6 x86_64

Perl:5.22

模块在模块加载时缓存PID。通过执行以下post fork来修复它:

$MCE::Signal::main_proc_id = $$;
require Worker;
Worker::run();
更好的是,将MCE的装载延迟到货叉之后。我会搬家的

use MCE::Loop;
use MCE::Signal '-setpgrp';
将子代码移动到同一模块中名为
run
的子模块中(例如
Worker.pm
),然后执行以下post操作:

$MCE::Signal::main_proc_id = $$;
require Worker;
Worker::run();

脚本

#!/usr/bin/perl

use strict;
use warnings;

use POSIX qw( setsid );

my $name = shift;

my @pids;
while (@pids < 2) {
    my $pid = fork();

    if (!defined $pid) {
        print "Can't fork: $!\n";
    }

    elsif ($pid == 0) {
        (setsid() != -1)
            or die "Can't start a new session: $!";

        require Worker;
        Worker::run($name);
        exit;
    }

    else {
        print $pid."\n";
        push(@pids, $pid);
    }
}

for my $pid (@pids) {
    waitpid($pid, 0);
}

您发送了SIGTERM,但父级收到了SIGINT?
kill('INT',$是\u MSWin32?-$:-getpgrp)::可能是信号造成的。@ikegami谢谢你的回答。我黑客攻击了Signal.pm,有许多进程组被终止的实例,这些终止中也有对$main_proc_id(父pid)的引用。我相信有一个适当的方法来解决这个问题,但这似乎是根本原因。谢谢调用
setpgrp
难道不起作用吗?我很早就试过了(注释仍在上面的脚本中),但问题仍然存在。这个问题似乎与MCE::Signal将HUP、INT、QUIT和TERM分配给\&stop_和_exit这一事实有关。为了获得我想要的功能,我必须在子进程中使用setpgrp,并在脚本中将$SIG{TERM}设置回默认值。这允许我在不影响父进程的情况下终止子进程组;到Worker.pm(我将其重命名)的顶部,但在其他方面,这非常有效!谢谢你花时间和我一起完成这件事。我将能够很快地将其应用到我的主程序中。:)啊,这周我第二次忘了。固定的。