【问题标题】:perl Thread::Queue not dequeueing all itemsperl Thread::Queue 没有使所有项目出队
【发布时间】:2012-11-06 20:14:07
【问题描述】:

我正在使用 perl 的 Thread::Queue 模块来保持线程池忙于下载我正在开发的简单爬虫的 url。使用Thread::Queue,我将一个哈希引用列表(准确地说是360)排入队列,其中每个哈希都包含有关单个url的信息:

#set up thread queue
my $THREADS=30; # Number of threads
my $url_q = Thread::Queue->new(); # Work to do
my $url_arr = urls();

my $count = 0;
for(@$url_arr) { 
    print "ENQUEUEING $_->{'url'}\n";
    $url_q->enqueue($_);
    $count++;
}

print "COUNT $count\n";
print "QUEUE COUNT " . $url_q->pending() . "\n";

threads->create( sub { 
            while(my $url_h = $url_q->dequeue()) { 
                print "url: $url_h->{'url'}\n\n";
                print "PENDING: " . $url_q->pending() . "\n";
                process_url($url_h);
            }
        }) for (1..$THREADS);   

$url_q->end;
print "WAITING\n";
$_->join() for threads->list;
print "DONE WAITING\n";

问题是我看到所有 360 个 url 都被排入队列,但是我只看到待处理的数字下降到 260 左右,这意味着只有大约 100 个真正得到评估,而 260 从来没有?我用 Thread::Queue 做错了什么吗?谢谢!

【问题讨论】:

  • 当它下降到 260(退出或停止工作)之后会发生什么?
  • 这是一个一直在循环的循环,所以它会继续循环的下一次迭代,并开始处理下一个 360 url。
  • 网络请求可以是异步的,你不需要线程。
  • 这意味着线程退出,所以$url_h 为假或线程死亡。首先找出哪个(使用eval { })。
  • 您可能将一个错误值(0,空字符串,undef)排队,导致循环终止并且线程退出。

标签: multithreading perl


【解决方案1】:

您确定没有看到任何错误?当我运行您的代码时,我看到“无法通过包“Thread::Queue”找到对象方法“end””。查看 Thread::Queue 的文档,我没有看到任何关于 end 函数的提及,所以这可能是您的代码中的一个错误。在我的测试中,每当调用 $url_q->end 时,“PENDING”计数器都会停止,这取决于您的计算机速度、当前负载以及它如何调度线程。可能是在你的盒子上,这发生在大约 260 处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 2016-10-14
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    相关资源
    最近更新 更多