4

我正在使用一个包含大量 url(数万个)的数据库。我正在尝试多线程解析器,它只是尝试解析给定的域。成功后,它将结果与数据库中的当前内容进行比较。如果不同,则更新结果。如果失败,它也会更新。

自然,这将产生过多的数据库调用。为了澄清我对实现某种形式的异步负载分配的最佳方法的一些困惑,我有以下问题(对于 Perl 来说还是相当新的)。

  1. 分配工作负载的最佳选择是什么?为什么?
  2. 我应该如何在生成之前收集要解析的 URL?
    • 用要比较的数据创建域的散列似乎对我来说最有意义。然后将其拆分,启动子项,子项将更改返回给父项
  3. 应该如何以干净的方式处理向父级返回数据?

我一直在玩一种更 Python 的方法(鉴于我在 Python 方面有更多经验),但由于某种原因缺乏阻塞,我还没有让它工作。除了这个问题,线程并不是最好的选择,仅仅因为每个线程(缺乏)CPU时间(另外,我在Perl通道中不止一次被钉在十字架上使用线程:P并且有充分的理由)

下面是我一直在为我的线程使用的或多或少的伪代码(它应该更多地用作我对我正在尝试完成的事情的解释的补充,而不是任何东西)。

# Create children...
for (my $i = 0; $i < $threads_to_spawn; $i++ )
{
    threads->create(\&worker);
}

然后,父级坐在一个循环中,监视一个共享的域数组。如果它变空,它会锁定并重新填充它。

4

1 回答 1

3

您的代码是持久工作者模型的开始。

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

use constant NUM_WORKERS => 5;

sub work {
   my ($dbh, $job) = @_;
   ...
}

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

   for (1..NUM_WORKERS) {
      async {
         my $dbh = ...;
         while (my $job = $q->dequeue()) 
            work($dbh, $job);
         }
      };
   }

   for my $job (...) {
      $q->enqueue($job);
   }

   $q->end();
   $_->join() for threads->list();
}

性能提示:

  • 根据您的系统和工作负载调整工作人员的数量。
  • 将小作业分组为大作业可以通过减少开销来提高速度。
于 2013-06-17T23:17:46.980 回答