【问题标题】:thread shared perl线程共享 perl
【发布时间】:2012-08-28 22:35:30
【问题描述】:

我写了一个代码,我需要让它成为多线程的。 Evething 有效,但每个循环重复 4 次:

use LWP::UserAgent;
use HTTP::Cookies;
use threads;
use threads::shared;

$| = 1;

$threads = 4;
my @groups :shared = loadf('groups.txt');

my @thread_list = ();
$thread_list[$_] = threads->create(\&thread) for 0 .. $threads - 1;
$_->join for @thread_list;
thread();

sub thread
{
    my $url = 'http://www.site.ru/';
    my $response = $web->post($url, Content =>
                    ['st.redirect' => ''
                    ]);
    foreach $i (@groups)
    {

        my $response  = $web->get($i);
        if(!($response->header('Location')))
        {
            ---------;
        }
        else
        {
            ----------;
        }

    }

}

sub loadf {
    open (F, "<".$_[0]) or erroropen($_[0]); 
    chomp(my @data = <F>);
    close F;
    return @data;
}

groups.txt:

http://www.odnoklassniki.ru/group/47357692739634
http://www.odnoklassniki.ru/group/56099517562922

我知道我需要使用threads::shared;但我无法理解如何使用它。


您的帖子没有太多上下文来解释代码部分;请更清楚地解释您的情况。

【问题讨论】:

  • 你期望什么行为,你得到了什么?您是否可以删除代码中不重要的部分以提供一个最小的示例?见sscce.org

标签: multithreading perl


【解决方案1】:

问题是你永远不会从@groups 中删除,所以所有线程都在@groups 中完成所有工作。

这是一个解决方案。

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

my $NUM_WORKERS = 4;

sub worker {
   my ($url) = @_;
   ... download the page ...
}

my $q = Thread::Queue->new();
for (1..$NUM_WORKERS) {
   async {
      while (my $url = $q->dequeue()) {
         worker($url);
      }
   };
}

$q->enqueue($_) for loadf('groups.txt');
$q->end();
$_->join() for threads->list;

【讨论】:

  • 如果你想要进程而不是线程,只需在顶部添加use forks;
【解决方案2】:

为什么需要让它线程化?在大多数情况下,perl 使用 fork 会做得更好。

也就是说,您的代码启动了 4 个线程,每个线程处理 @groups 中的所有内容。听起来那不是你想要做的。如果您希望 @groups 成为工作队列,请查看 Thread::Queue(或 Parallel::ForkManager)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-11
    • 2018-07-15
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 2017-05-05
    相关资源
    最近更新 更多