multithreading - Perl线程共享数据

标签 multithreading perl shared

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

my @ThreadInput   :shared=();
my @ThreadOutput  :shared=();

最佳答案

(我将把填充 @ThreadInput 并使用 @ThreadOutput 的线程命名为“调用者”。)

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

所以,

如果调用者在worker启动之前填充@ThreadInput,则@ThreadInput不需要共享,但会避免为每个worker创建数组的副本如果是的话。

如果调用者在工作线程启动后填充@ThreadInput,则必须共享@ThreadInput。如果不是,调用者的 @ThreadInput 中的更改不会影响工作线程的副本。

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


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

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

关于multithreading - Perl线程共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16906488/

相关文章:

java - Perl 客户端到 JAX-WS java 服务器问题

perl - 在 perl 中, '$' 的括号列表在子声明中意味着什么?

matlab - 无源码matlab函数分发

c++ - C linux中服务器和客户端之间的共享内存

c++ - <Windows>为什么 std::thread::native_handle 返回类型为 'long long unsigned int' 的值而不是 void*(又名 HANDLE)?

c - 提高多线程程序的速度

java - 这是一个好的多线程服务器设计吗?

c# - web服务中文件下载多线程并发的问题

perl - 如何使用 WWW::Mechanize 保存图像的宽度、高度和字节?

c - 复杂类型的 mmap 问题