在我的脚本中,有 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/