【问题标题】:Perl, Children, and Shared DataPerl、子项和共享数据
【发布时间】:2013-06-13 22:57:51
【问题描述】:

我正在使用一个包含大量 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);
}

然后,父节点会进入一个循环,监视共享的域数组。如果它变空,它会锁定并重新填充它。

【问题讨论】:

  • 如果您想使用进程而不是线程,只需使用线程编写代码,然后将use threads 替换为use forks。这也允许孩子“返回”数据,就像使用线程一样。
  • “另外,我在 Perl 频道中不止一次因为使用线程 :P 而被钉死在十字架上,这是有充分理由的”。你不应该的。如果非常有效,则正确使用线程。
  • @ikegami:假设域解析代码中的所有内容都是线程安全的......
  • @ysth,他被告知他对使用线程(大概是为了想象中的性能问题)而不是在线程中使用不是线程安全的代码而疯狂。两种不同的东西。
  • @ysth,这就是重点。似乎没有给出任何理由,所以很有可能这是通常的货物崇拜偏见。

标签: mysql multithreading perl multiprocessing children


【解决方案1】:

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

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();
}

性能提示:

  • 根据您的系统和工作负载调整工作人员的数量。
  • 将小型作业组合成大型作业可以通过减少开销来提高速度。

【讨论】:

  • 您是否假设所有作业都同时排队?听起来它们可能只能分批使用,理想情况下,您不会为每个批次重新启动所有工作线程
  • @ysth,不,可以添加它们,直到您致电 end。您可以根据需要推迟拨打end。他们将在他们进来时执行。如果没有要执行的工作,工人将阻塞,直到有工作进来。
  • @ikegami,一个持久的工作者模型正是我所追求的。谢谢你的模型!你会建议从线程转移到子进程吗?
  • @ysth 作业实际上是从数组中拉出一行(或一组行)(阻塞直到完成)并继续前进。队列清空时父阻塞,重新加载它,完成时广播。
  • @geudrik,我建议移动到流程吗?不,除非它解决了问题。如果您遇到工作人员崩溃的问题,流程可能会更好地工作。 // 另一方面,如果您只是询问是否应该使用线程或进程,请使用您喜欢的任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
  • 2014-11-30
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
相关资源
最近更新 更多