2014-03-04 57 views
5

我有一對長期運行perl腳本在windows(草莓perl),我正在工作。perl Win32 Perl之間的信號處理

  1. 第一個過程是父監視過程。它每24小時重新啓動一次子進程,並始終運行。
  2. 第二個是兒童支付處理腳本。這個過程必須完成它在關機前所做的任何事情。

這是我的理解,信號處理doesn't work perl在win32上,它不應該依靠。有其他方式可以處理信號嗎? Win32::Process::Kill似乎殺死了這個進程,卻沒有讓它安全關閉。

這是我試過的信號處理...

#Child 
my $interrupted = 0; 
$SIG{INT} = sub{$interrupted = 1;}; 
while(!$interrupted){ 
    #keep doing your thing, man 
} 

#Parent 
my $pid = open2(\*CHLD_OUT,\*CHLD_IN,'C:\\strawberry\\perl\\bin\\perl.exe','process.pl'); 
kill INT=>$pid; 
waitpid($pid,0); 

我能想到的唯一的另一件事就是打開兩個進程之間的套接字和寫入通過套接字消息。但一定有一些更容易的事情。任何人都知道任何可以做到這一點的模塊?

更新

我已經開始工作由opening a socket創建通過IO::Socket::INETIO::Select一個 「信號」 機制。這似乎工作,我正在考慮編寫一個與AnyEvent兼容的模塊。但我仍然對一個不需要打開偵聽端口並且不需要服務器/客戶端關係的實現感興趣。是否可以通過在Windows中訂閱和觸發自定義事件來完成此操作?

回答

0

嗯,一個有趣的問題。有一件事我會想知道 - 將代碼重寫爲線程有多可行?

當遇到類似的問題時,我發現將「子」進程封裝爲一個線程意味着我可以更好地從父進程「管理」進程。

如:

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

use threads; 
use threads::shared; 

my $interrupted : shared; 

sub child { 
    while (not $interrupted) { 
     #loop; 
    } 
} 


#main process 

while (1) { 
    $interrupted = 0;  
    my $child = threads -> create (\&child);  
    sleep 60; 
    $interrupted = 1; 
    $child -> join(); 
    sleep (3600); 
} 

但是,因爲你已經從線程得到了公益機構 - 你有Thread::Queuethreads::sharedThread::Semaphore和 - 我至少相當肯定,您可以發送僞「殺」信號在腳本內。這是因爲線程也在內部模擬'kill'信號。

http://www.perlmonks.org/?node_id=557328

添加到您的線索:

$SIG{'TERM'} = sub { threads->exit(); }; 

然後那麼你的 '主' 可以:

$thr->kill('TERM')->detach(); 
0

隨着的ActiveState Perl的我通過Win32::Event使用Windows本地事件模塊。

這樣你就不需要實現任何奇特的東西,甚至可以讓你的腳本與本地應用程序進行交互。我在許多應用程序中使用這個模組。

由於它是使用本機代碼的Win32::IPC的一部分,因此可能無法用於草莓Perl 。如果是這種情況,您可以嘗試從CPAN來源進行編譯。如果你有很多基於Windows perl的軟件,可能值得一試。