【问题标题】:Reading files recursively in parallel in Perl在 Perl 中以递归方式并行读取文件
【发布时间】:2013-05-10 04:32:17
【问题描述】:

我有 500 个要读取的文件,但以递归方式读取每个文件大约需要 2 分钟。所以我想使用 Perl 并行执行此操作。我该怎么做?

【问题讨论】:

  • 您可能想了解fork 及其后果。
  • 我认为您的意思不是“递归”。我无法想象递归文件读取可能是什么。也许您的意思是“依次”

标签: perl


【解决方案1】:

如果需要两分钟,您正在谈论大量阅读。您基本上是在等待硬盘驱动器。文件是否在单独的硬盘驱动器上?如果不是,您为什么认为尝试同时获取第二个文件会更快?事实上,它可能会通过增加硬盘驱动器的搜索量来使事情变慢。

但如果你想尝试一下,

use threads;
use Thread::Queue qw( );

use constant NUM_WORKERS => 4;  # Twiddle this

sub run {
   my ($qfn) = @_;
   ...read file $qfn here...
}

my $q = Thread::Queue->new();

my @threads;
for (1..NUM_WORKERS) {
   push @threads, async {
      while (my $job = $q->dequeue()) {
         run($job);
      }
   };
}

$q->enqueue($_) for @qfns;

$q->enqueue(undef) for @threads;
$_->join() for @threads;

【讨论】:

    【解决方案2】:

    创建一个 Perl 脚本来处理单次罚款。创建一个 shell 脚本 batch-run.sh,它包含 500 行(类似 perl perl-script.pl file001 的行)。然后创建另一个 shell 脚本,启动所需数量的后台进程以执行来自batch-run.sh 的行。不过,您可能希望限制后台进程的数量。像这样的:

    NCPUS=32 # number of parallel processes
    ISCRIPT=batch-run.sh
    NTASKS=$(wc -l $ISCRIPT | cut -d' ' -f1)
    
    runbatch() {
        OFFSET=$1
        while [ $OFFSET -le $NTASKS ]; do
            CMD=$(sed "${OFFSET}q;d" $ISCRIPT)
            echo "$CMD ..."
            eval $CMD
            let OFFSET+=$NCPUS
        done
    }
    
    for i in $(seq 1 $NCPUS); do
        runbatch $i &
    done
    wait
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-28
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 2015-07-31
      • 2011-07-20
      • 1970-01-01
      相关资源
      最近更新 更多