在我的腳本中有n個工作線程(0,1..n-1),每個工作在以下數組的第N個項目上。輸入數組用於向線程提供輸入,輸出數組接受線程的輸出。線程不會訪問數組的其他項目。在那種情況下,我應該聲明數組是共享的嗎?Perl線程共享數據
my @ThreadInput :shared=();
my @ThreadOutput :shared=();
在我的腳本中有n個工作線程(0,1..n-1),每個工作在以下數組的第N個項目上。輸入數組用於向線程提供輸入,輸出數組接受線程的輸出。線程不會訪問數組的其他項目。在那種情況下,我應該聲明數組是共享的嗎?Perl線程共享數據
my @ThreadInput :shared=();
my @ThreadOutput :shared=();
,除非標有:shared
(我的名字「主叫方」用於填充@ThreadInput
和消耗@ThreadOutput
線程)。
Perl的變量不是線程之間共享。每個線程獲得副本未標記爲:shared
的變量。
所以,
如果呼叫者填充@ThreadInput
工人開始之前,@ThreadInput
並不需要共享,但它會避免每個工人創建數組的一個副本,如果它是。
如果在工作人員啓動後呼叫者填充@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;
}
加入我的回答。 – ikegami
如果數據不共享,每個線程都在一個單獨的*拷貝操作*。這可能對於輸入是可以的,但對於輸出來說似乎不是一個好的解決方案。 – amon