【发布时间】:2017-12-18 14:25:08
【问题描述】:
我第一次尝试使用 fork 时遇到问题。
脚本似乎运行良好,直到我需要它退出 fork 并返回主脚本。
而是完全退出脚本。
my @files = glob( "./input/<Input subnets>.txt" ) or die "Can't open HostInventory$!"; # Open the Host Inventory csv files for parsing
foreach my $file ( @files ) {
open (CONFIG, '<', $file) or die "Can't <Input subnets>.txt$!";
my @lines = <CONFIG>;
chomp (@lines);
$m = scalar @lines / 10;
for ( $m ) {
s/\..*//g
};
for ( my $i = 0; $i < @lines; $i += $m ) {
# take a slice of elements from @files
my @lines4 = @lines[$i .. $i + $m];
if ( fork() == 0 ) {
for my $n ( @lines4 ) {
system("Nmap -dns-servers <IP of DNS server> -sn -v $n -oX ./input/ip360_DNS/ip360_DNS$n.xml --send-eth --reason");
}
exit;
}
}
wait for 0 .. @lines/$m;
}
此时它应该在父脚本中继续并打开一个解析扫描输出的子例程。相反,它会完全退出脚本。
我做错了什么?
-=-=-=-=更新-=-=-=-= 我尝试了下面的 Parallel::ForkManager 示例。当作为独立进程运行时,它可以完美运行。我在子例程中运行代码,当我尝试这样做时,Perl 解释器崩溃了。有什么建议吗?
#1/usr/bin/perl -w
use Parallel::ForkManager;
use strict; # Best Practice
use warnings; # Best Practice
use Getopt::Long; # Add the ability to use command line options
if (!@ARGV) {
&help;
exit 1
}
GetOptions(
full => \&full,
temp => \&temp,
);
#######################################################################
#######################################################################
# #
# Call each function #
# #
#######################################################################
#######################################################################
sub temp {
&speak;
&simple;
&speak2;
exit;
}
sub full {
&speak;
&simple;
&speak2;
exit;
}
sub speak {
print "This is where I wait for 2 seconds\n";
sleep (2);
}
my $process = $$;
print "$process\n";
sub simple {
my $pm = new Parallel::ForkManager(10);
$pm->run_on_finish(
sub { $process;
print "** PID $process\n";
}
);
my @files = glob( "./ping.txt" ) or die "Can't open CMS HostInventory$!"; # Open the CMS Host Inventory csv files for parsing
foreach my $file (@files){
open (CONFIG, '<', $file) or die "Can't ip360_DNS File$!";
my @lines = <CONFIG>;
chomp (@lines);
foreach my $n (@lines) {
# Forks and returns the pid for the child:
my $pid = $pm->start and next;
# ... do some work with $data in the child process ...
system("ping $n >> ./input/$n.txt");
}
$pm->finish; # Terminates the child process
}
}
sub speak2 {
print "In new subroutine\n";
}
【问题讨论】:
-
Parallel::ForkManager 会让你的生活更轻松。
-
fork()创建第二个进程,它是原始进程的精确副本。原件继续运行,副本也继续运行。分叉进程没有“返回”。 -
@Jim Garrison,他们并没有从字面上使用“返回”这个词。他们希望父母等待孩子完成,然后继续执行其他代码。
-
补充@Jim_Garrison 所说的,你想“使用线程;线程->创建(\&worker_fxn);”而不是 fork() - 谷歌 perl 线程与分叉之间有什么区别。