Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Perl线程共享数据_Multithreading_Perl_Shared - Fatal编程技术网

Multithreading Perl线程共享数据

Multithreading Perl线程共享数据,multithreading,perl,shared,Multithreading,Perl,Shared,在我的脚本中,有n个工作线程(0,1..n-1),每个工作线程处理以下数组的第n项。输入数组用于向线程提供输入,输出数组接受线程的输出。线程不会访问数组的其他项。在这种情况下,我应该将数组声明为共享的吗 my @ThreadInput :shared=(); my @ThreadOutput :shared=(); (我将把填充@ThreadInput并使用@ThreadOutput的线程命名为“caller”) Perl变量不会在线程之间共享,除非标记为:shared。每个线程获取一个

在我的脚本中,有n个工作线程(0,1..n-1),每个工作线程处理以下数组的第n项。输入数组用于向线程提供输入,输出数组接受线程的输出。线程不会访问数组的其他项。在这种情况下,我应该将数组声明为共享的吗

my @ThreadInput   :shared=();
my @ThreadOutput  :shared=();
(我将把填充
@ThreadInput
并使用
@ThreadOutput
的线程命名为“caller”)

Perl变量不会在线程之间共享,除非标记为
:shared
。每个线程获取一个未标记为
:shared
的变量副本

所以

如果调用方在工作线程开始之前填充了
@ThreadInput
,则不需要共享
@ThreadInput
,但如果每个工作线程都是,它将避免为每个工作线程创建数组的副本

如果调用方在worker启动后填充
@ThreadInput
,则必须共享
@ThreadInput
。如果不是,则调用方的
@ThreadInput
中的更改不会影响辅助进程的副本

@ThreadOutput
必须共享。如果不是,工作线程的
@ThreadOutput
中的更改不会影响调用方的副本


使用该模型重用工人将非常困难。您可能应该使用类似以下内容的内容:

use threads;
use Thread::Queue 1.03;   # or Thread::Queue::Any

use constant NUM_WORKERS => ...;

sub handle_request {
    my ($request) = @_;
    return ...response...;
}


如果数据不共享,每个线程将在单独的副本上操作。这对于输入来说可能还可以,但对于输出来说似乎不是一个好的解决方案。
{
   my $request_q  = Thread::Queue->new();
   my $response_q = Thread::Queue->new();

   my @threads;
   my $threads;
   for (1..NUM_WORKERS) {
      ++$threads;
      push @threads, async {
         while (my $request = $request_q->dequeue()) {
            $response_q->enqueue([ $request => handle_request($request) ]);
         }

         $response_q->enqueue(undef);
      };
   }

   ... Add stuff to queue $request_q->enqueue(...) ...

   $request_q->end();  # Can be done later if you want to add more items later.

   while ($threads && my $job = $response_q->dequeue()) {
      if (!defined($job)) {
         --$threads;
         next;
      }

      my ($request, $response) = @$job;
      ... handle response ...
   }

   $_->join for @threads;
}