我一直在嘗試使用Perl編寫一個簡單的ping掃描器供內部使用。由於它掃描24位CIDR網絡,如果腳本運行在單個線程中,該腳本運行時間過長。我曾嘗試添加fork功能來加速此過程,但由於在任何給定時間只有一個子進程處於活動狀態,因此我的first attempt幾乎同時發生。爲什麼我的Perl程序在fork之後不會收穫子進程?
我的perlipc文件中以及在Perl Cookbook兒童進程讀取並與第二版本出來了:
##Install the CHLD SIG handler
$SIG{CHLD} = \&REAPER;
sub REAPER {
my $childPID;
while (($childPID = waitpid(-1, WNOHANG)) > 0) {
print "$childPID exited\n";
}
$SIG{CHLD} = \&REAPER;
}
my $kidpid;
for (1 .. 254) {
my $currIP = join ".", (@ipSubset[0,1,2], $_);
die "Could not fork()\n" unless defined ($kidpid = fork);
if ($kidpid) {
#Parent process
#Does nothing
}
else {
#Child process
my $pingConn = Net::Ping->new(); #TCP
say "$currIP up" if $pingConn->ping($currIP);
$pingConn->close();
#Nothing else to do
exit;
}
}
say "Finished scanning $ipRange/24";
當我掃描我的內部網絡輸出爲:
$perl pingrng2.pl 192.168.1.1
192.168.1.2 up
5380 exited
192.168.1.102 up
192.168.1.100 up
5478 exited
5480 exited
Finished scanning 192.168.1.1/24
從結果中可以看出,執行成功掃描的線程打印「up」消息,乾淨地退出並由父進程收割。與此同時,其他的251個線程仍然掛在'/ sbin/init'上,這可以通過一個快速的'ps -ef'列表來看到。如果我在退出語句之前在子處理塊中添加了'print'Child:$ currIP結尾\ n「',我的終端上剩餘的251個進程的輸出」在我的perl腳本退出後。
這是怎麼回事?我認爲與waitpid循環結合的$ SIG {CHLD}子例程將收穫所有的子進程,並確保系統中不存在殭屍/懸掛進程。
同樣我還希望能夠在任何給定的時間運行特定數量的子進程,比如說,'n'個併發運行的子進程,只要有一個退出父進程就會啓動另一個子進程但在任何特定時刻只有'n'個孩子。這可能嗎?如果是,我可以得到一些僞代碼來幫助指導我?
爲什麼你的循環從1-254(253?)而不是0-255? – 2009-05-31 05:03:28
Matt Boehm 255通常是廣播地址(假設是/ 24子網)。 0也有特殊含義(在/ 24),但我忘記它是什麼。 – 2009-05-31 05:59:08