【发布时间】:2014-06-03 15:59:53
【问题描述】:
我有一个递归函数,它调用系统命令来列出文件和目录。对于每个目录,它都会再次调用自己。
此过程可能需要一段时间。这就是我想运行并行作业的原因。
我正在研究 ForkManager,但它不允许创建新的子分支。由于子进程的数量应限制为 10,我在考虑“工人”的概念。有 10 个工人在等待作业执行。
我的递归函数:
sub pullDataFromDbWithDirectory {
my $_dir = $_[0];
my @list = ();
if ($itemCount lt $maxNumberOfItems) {
my @retval = grep { /dir|file/ } map { s/^Dir\s+|^File\s+|\n//g; $_ } qx($omnidb -filesystem $filesystem '$label' -listdir '$_dir');
foreach my $item (@retval) {
$itemCount++;
push(@list,$item) if $item =~ /^file/;
if ($item =~ /^dir/) {
my $subdir = "$_dir/$item";
$data{$subdir} = ();
if ($recursive) {
pullDataFromDbWithDirectory($subdir);
}
}
}
$data{$_dir} = \@list;
}
}
任何帮助将不胜感激。
更新:
问题解决了。感谢您的输入。我修改了我的代码:
sub pullDataFromDbWithDirectory {
my $_dir = $_[0];
if ($itemCount <= $maxNumberOfItems) {
my @retval = grep { /dir|file/ } map { s/^Dir\s+|^File\s+|\n//g; $_ } qx($omnidb -filesystem $filesystem '$label' -listdir '$_dir');
foreach my $item (@retval) {
$itemCount++;
my $file = "$_dir/$item";
push(@data,$file);
if ($item =~ /^dir/) {
$worker->enqueue($file);
print "Add $file to queue\n" if $debug;
}
}
}
}
sub doOperation () {
my $ithread = threads->tid();
while (my $folder = $worker->dequeue()) {
print "Read $folder from queue\n" if $debug;
pullDataFromDbWithDirectory($folder);
}
}
my @threads = map threads->create(\&doOperation), 1 .. $maxNumberOfParallelJobs;
pullDataFromDbWithDirectory($directory);
$worker->enqueue((undef) x $maxNumberOfParallelJobs);
$_->join for @threads;
【问题讨论】:
-
您需要为此进行进程间通信。支持 IPC 的一个模块是 Child:metacpan.org/pod/Child
-
递归地发现目标目录,然后并行处理它们是否可以接受?如果您不是特别需要子叉,不妨使用最简单的方法。
-
问题是我必须运行omnidb 命令来列出文件和文件夹。而且它不支持递归列表。 Foreach 子文件夹我必须运行omnidb 命令,这需要相当长的时间。我想并行运行它们。也许将目录填充到正在并行处理的队列中..
-
看看GNU parallel。
标签: perl recursion parallel-processing