2015-10-19 127 views
1

我在Windows上使用Strawberry Perl。我有一些GUI.pl應用程序運行script.pl其中運行some.exe。 perl腳本作爲GUI應用程序和some.exe之間的STDIN/OUT/ERR的代理。 問題是我無法殺掉鏈式GUI.pl中的some.exe進程 - > script.pl - > some.exe。Perl信號處理程序和WIndows

GUI.pl發送任期script.pl

# GUI.pl 
my $pid = open my $cmd, '-|', 'script.pl'; 
sleep 1; 
kill 'TERM', $pid; 

script.pl抓 'TERM' 並試圖殺死some.exe

# script.pl 
$SIG{TERM} = \&handler; 
my $pid = open my $cmd, '-|', 'some.exe'; 
sub handler { 
    kill 'TERM', $pid; 
} 

隨着這個方案中,some.exe的進程繼續執行。我已經瞭解了很多關於信號的知識,但仍不明白如何解決這個問題。

提前致謝。


而且它使用的threads的解決方案之一:

# script.pl 
use threads; 
use threads::shared; 

$SIG{BREAK} = \&handler; 

my $pid :shared; 

async { 
    $pid = open my $cmd, '-|', 'some.exe' 
}->detach; 

# 1 second for blocking opcode. After sleep handler will be applied 
sleep 1;  

sub handler { 
    kill 'TERM', $pid; 
} 

回答

0

我會警惕在Windows上使用「殺」信號的,因爲他們是一個POSIX事情。 http://perldoc.perl.org/functions/kill.html

但我覺得這裏的問題可能是是因爲Deferred Signals。具體而言,如果您向某個流程發送信號,解釋器會一直等到「安全」處理它。在「some.exe」中間不太可能。

以這種方式使用kill信號並不是特別好的IPC形式。請參閱perlmonks: Signals Vs. Windows進行一些有用的討論。

+0

這種解釋是錯誤的。 Windows信號不使用遞延信號記錄的延期過程。 – ikegami

+0

我在這個解釋中發現我在IO操作期間無法處理信號。 –

0

Windows上的信號非常特殊。 INTQUIT信號比TERM更好。我對Perl和Windows如何處理信號的廣泛研究總結爲here

TL; DR:在Windows上,TERM可以終止Windows中的進程,但無法處理。 INTQUIT可以被處理,並且它們的默認行爲是終止該過程。如果你使用Windows僞進程(這是你在Windows中調用fork時得到的結果),那麼事情會變得更加複雜。

+0

'kill TERM => $ pid' [發送Ctrl-Break](http://perl5.git.perl.org/perl.git/blob/3ec400f5ce53ea1a56d283bc6bf59e75762df058:/win32/win32.c#l1258),它可以是[處理](http://perl5.git.perl.org/perl.git/blob/3ec400f5ce53ea1a56d283bc6bf59e75762df058:/win32/win32.c#l2142)。 [我無法驗證這一點,因爲出於某種原因我無法處理任何信號。] – ikegami