在Perl中执行进程,使用IPC提供停止、恢复和终止选项

在Perl中执行进程,使用IPC提供停止、恢复和终止选项,perl,process,fork,exe,execution,Perl,Process,Fork,Exe,Execution,我几乎不知道用叉子叉。我试着研究,但找不到一个简单的例子来说明如何做这些事情。对于windows,我找到了一个很好的模块,并编写了这段代码,这正是我想要的 Win32::Process::Create( my $ProcessObj, "$jobs{$id}->{path}", "execute job", 0, NORMAL_PRIORITY_CLASS, "." ) || die ErrorReport(); print "Available commands:\n1

我几乎不知道用叉子叉。我试着研究,但找不到一个简单的例子来说明如何做这些事情。对于windows,我找到了一个很好的模块,并编写了这段代码,这正是我想要的

   Win32::Process::Create( my $ProcessObj,
    "$jobs{$id}->{path}", "execute job", 0, NORMAL_PRIORITY_CLASS, "." )
  || die ErrorReport();
print "Available commands:\n1.Suspend\n2.Resume\n3.Kill\n";
while (1) {
    chomp( my $input = <STDIN> );
    if ( $input eq "1" ) {
        $ProcessObj->Suspend();
    }
    if ( $input eq "2" ) {
        $ProcessObj->Resume();
    }
    if ( $input eq "3" ) {
        print "Returned to main menu.\n";
        $ProcessObj->Kill(0);
        return;
    }
}
我有一个程序,它每3秒钟打印一次Hello world,如果这个例子有帮助的话,我想暂停、恢复并杀死它。

使这个过程变得简单且独立于平台

use Forks::Super;
...
my $pid = fork { exec => $jobs{$id}->{path} };
...
$pid->suspend;
...
$pid->resume;
...
$pid->kill;       # or $pid->kill('TERM'), $pid->kill('QUIT'), etc.

如果必须用手操作,则使用的信号是
'SIGSTOP'
'SIGCONT'

命令行演示

perl -wE'
    $pid = fork // die "Cant fork: $!"; 
    if ($pid == 0) { 
        for (1..6) { say "\tkid ..."; sleep 1; }; 
        say "\tKID DONE"; exit; 
    }; 
    sleep 3; 
    kill "STOP", $pid; 
    for (1..2) { say "Parent here!"; sleep 1}; 
    kill "CONT", $pid; 
    wait;    
'
印刷品

kid ... kid ... kid ... Parent here! Parent here! kid ... kid ... kid ... KID DONE 这需要更多的细节,但它确实显示了涉及到什么样的事情

输出(带注释)

家长:19628年开始 1#在启动几秒钟后输入 家长:19628 2#等了一分钟 家长:续19628 3#再等几秒钟 父母:19628年出生 ^C#退出STDIN 我们允许孩子打印一个文件几秒钟(几次),然后停止(1),然后等待一段时间,然后使用孩子(2),让孩子在杀死它之前再打印几次(3)


输出
kidfile.out
有几行来自子级,然后是一行来自父级,然后是几行来自子级,确认子级已暂停、恢复和停止。

ehh,模块安装失败:( kid ... kid ... kid ... Parent here! Parent here! kid ... kid ... kid ... KID DONE
use warnings;
use strict;
use feature 'say';    
#use IO::Handle;            # needed pre v5.16 (for autoflush)

my $fh_kid;
$SIG{INT} = sub { close $fh_kid; exit 1 };

my $file = 'kidfile.out';
open $fh_kid, '>', $file or die "Can't open $file: $!";
$fh_kid->autoflush;

my $pid = fork // die "Can't fork: $!";

if ($pid == 0) {
    $SIG{TERM} = sub { close $fh_kid; exit 1 };
    for (1..20) { 
        say $fh_kid "\tkid, $_"; 
        sleep 1;
    }   
    exit;
}
say "Parent: started $pid";

while (1) {
    chomp (my $input = <STDIN>);
    if (not $input) {
        close $fh_kid; 
        last;
    }   
    if ($input == 1) {
        kill 'STOP', $pid;
        say         "Parent: STOP-ed $pid";
        say $fh_kid "Parent STOP-ed $pid";
    }   
    elsif ($input == 2) {
        say "Parent: CONT the $pid";
        kill 'CONT', $pid;
    }   
    elsif ($input == 3) {
        close $fh_kid;
        kill 'TERM', $pid;
        say "Parent: TERM-ed the $pid";
    }   
}

my $gone = waitpid $pid, 0;

if    ($gone > 0) { say "Child $gone exited with: $?" }
elsif ($gone < 0) { say "No such process ($gone), reaped already?" }
else              { say "Still out there?" }
Parent: started 19628 1 # entered a few seconds after starting Parent: STOP-ed 19628 2 # after waiting for a minute Parent: CONT the 19628 3 # after waiting for a few more seconds Parent: TERM-ed the 19628 ^C # quit STDIN