Perl:正确传递数组以供线程使用 [英] Perl: Correctly passing array for threads to work on

查看:98
本文介绍了Perl:正确传递数组以供线程使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习如何在Perl中进行线程化.我正在查看示例代码此处并略微修改了解决方案代码:

I'm learning how to do threading in Perl. I was going over the example code here and adapted the solution code slightly:

#!/usr/bin/perl
use strict;
use warnings;
use threads;
use Thread::Semaphore;

my $sem = Thread::Semaphore->new(2); # max 2 threads
my @names = ("Kaku", "Tyson", "Dawkins", "Hawking", "Goswami", "Nye");
my @threads = map {
    # request a thread slot, waiting if none are available:
    foreach my $whiz (@names) {
        $sem->down;
        threads->create(\&mySubName, $whiz);
    }
} @names;

sub mySubName {
    return "Hello Dr. " . $_[0] . "\n";
    # release slot:
    $sem->up;
}

foreach my $t (@threads) {
    my $hello = $t->join();
    print "$hello";
}

当然,现在这已完全损坏,无法正常工作.导致此错误:

Of course, this is now completely broken and does not work. It results in this error:

C:\scripts\perl\sandbox>threaded.pl
Can't call method "join" without a package or object reference at C:\scripts\perl\sandbox\threaded.pl line 24.
Perl exited with active threads:
        0 running and unjoined
        9 finished and unjoined
        0 running and detached

我的目标有两个:

  • 强制执行任何给定时间允许的最大线程数
  • 提供工作"数组以供线程使用

在原始解决方案中,我注意到0..100;代码似乎指定了分配给线程的工作"量.但是,在我要提供一系列工作的情况下,是否还需要提供类似的东西?

In the original solution, I noticed that the 0..100; code seems to specify the amount of 'work' given to the threads. However, in my case where I want to supply an array of work, do I still need to supply something similar?

非常欢迎任何指导和更正.

Any guidance and corrections very welcome.

推荐答案

您要将foreach的结果存储到@threads中,而不是threads->create的结果中.

You're storing the result of foreach into @threads rather than the result of threads->create.

即使您解决了此问题,您收集完成的线程也为时已晚.我不确定这有多大的问题,但它可能会阻止在某些系统上启动64个以上的线程. (64是程序在某些系统上一次可以拥有的最大线程数.)

Even if you fix this, you collect completed threads too late. I'm not sure how big of a problem that is, but it might prevent more than 64 threads from being started on some systems. (64 is the max number of threads a program can have at a time on some systems.)

更好的方法是重用线程.这样既解决了两个问题,又避免了重复创建线程的开销.

A better approach is to reuse your threads. This solves both of your problems and avoids the overhead of repeatedly creating threads.

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

use constant NUM_WORKERS => 2;

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

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

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

   $q->enqueue(@names);  # Can be done over time.
   $q->end();            # When you're done adding.
   $_->join() for threads->list();
}

这篇关于Perl:正确传递数组以供线程使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆