内部で使用するために、Perl を使用して最低限の ping スキャナーを作成しようとしています。24 ビットの CIDR ネットワークをスキャンするため、スクリプトをシングル スレッドで実行すると、実行に時間がかかりすぎます。プロセスを高速化するために fork 機能を追加しようとしましたが、一度にアクティブな子プロセスが 1 つしかなかったため、最初の試行にはほぼ同じ時間がかかりました。
私はperlipcドキュメントとPerl Cookbookで子プロセスを読み、2 番目のバージョンを思いつきました:
##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' に接続されたままぶら下がったままになっています。exit ステートメントの直前の子処理ブロックに 'print "Child: $currIPending\n"' を追加すると、perl スクリプトが終了した「後」に、残りの 251 プロセスからの出力が端末に表示されます。
何が起きてる?$SIG{CHLD} サブルーチンと waitpid ループを組み合わせると、すべての子プロセスが取得され、システムにゾンビやダングリング プロセスが残らないようになると考えました。
同じ息で、特定の数の子プロセスをいつでも実行できるようにしたいと考えています。いつでも「n」人の子供よりも。これは可能ですか?はいの場合、私を導くのに役立つ疑似コードを入手できますか?