2015-04-24 39 views
0

我想生成一個進程,執行一些操作並在完成後手動將其終止。在Perl中刪除分叉的Windows進程

雖然它不工作。這個過程開始,我看到pid和while循環一直運行,直到我殺死它。

難道是Perl產生了一個新的shell,然後衍生出UI進程,當shell(Perl產生的)被殺死時,它不會被Perl殺死?

my $cmd = "notepad.exe"; 
my $sleepTime = 10;#60 * 10; 

$childPid = fork(); 
if ($childPid) 
{ # Parent 
    print "Started child process id: $childPid\n"; 
    sleep $sleepTime; 

    $SIG{CHLD} = 'IGNORE'; 
    while (kill(15, $childPid)) 
    { 
    my $numKilled = kill(SIGTERM, $childPid); 
    printf("numKilled: %s\n", $numKilled); 
    printf("numKilled: %s\n", $childPid); 
    sleep 1; 
    } 
} 

elsif ($childPid == 0) 
{ # Child 
    system($cmd); 
    exit 0; # will never get here 
} 
else 
{ # Unable to fork 
    die "ERROR: Could not fork new process: $!\n\n"; 
} 
+2

鑑於你的子進程是'notepad.exe',我猜你在Windows上。如果是這樣,你可能要明確提到,因爲Windows上的進程管理可能與在與Perl定型相關的* nix環境中有所不同。 –

+0

如果'$ childPid'爲'undef',那麼'$ childPid == 0'將計算爲* true *並且如果您啓用了警告,將導致'在數字eq(==)'警告中使用未初始化值$ childPid。這意味着最終的'else'子句將永遠不會被執行。您應該使用'elsif(定義的$ childPid)'代替。 – Borodin

+3

fork和signal都是在Windows上由Perl模擬的unix概念。這可能不是最好的方法。你有沒有考慮過使用Win32 :: Process? – ikegami

回答

1

Forks::Super模塊爲處理分叉過程提供了許多有用的工具,並提供了更便攜的接口。

該程序運行notepad來編輯程序自己的源文件並在5秒鐘後終止子進程。如果你需要傳遞參數給命令,那麼你應該把它指定爲這樣一個匿名的值數組。如果你使用一個字符串像cmd => qq<notepad "$0">代替,那麼你將開始CMD.EXE的副本這反過來開始的notepad.exe和kill命令將剛剛離開運行記事本作爲一個孤兒

use strict; 
use warnings; 

use Forks::Super; 

if (my $pid = fork({ cmd => [ 'notepad', $0 ] })) { 
    sleep 5; 
    Forks::Super::kill('TERM', $pid); 
    print "Killed\n"; 
} 

請注意,如果您想申請超時到子進程,那麼你可以寫

my $pid = fork({ cmd => 'notepad', timeout => 600 })