我試圖將子例程引用傳遞給perl線程來實現threadMap子例程。我處於一個我必須「自我推銷」大多數事物的環境中;安裝新的perl軟件包不是一種選擇。將子例程引用傳遞給perl線程
此外,我運行perl版本5.10。在我的工作環境中,perl> 5.10版本不可用。
我可以毫不費力地傳遞子例程引用。但是,一旦我嘗試將一個子例程引用傳遞給一個線程,該線程看起來並不理解它。
這裏是我提出的threadMap子程序,我認爲它的註釋對於感興趣的問題回答者來說足以解釋。
#input: hash with keys L (listref), f (function which can apply to each element of L), and optionally nThreads
#default for nThreads is 50
#divides L into sublists for each thread, then kicks off threads
#each thread applies f to each element of the sublist
#and then returns the result of $f on each item
#output: map{ &$f($_) } @{$L}, but done threadily
sub threadMap{
my %arg = @_;
my ($L,$f,$nThr) = ($arg{L},$arg{f},$arg{nThreads});
my $MAXTHREADS = 50;
if(not defined $nThr or $nThr > $MAXTHREADS){
$nThr = $MAXTHREADS;
}
&log(1,"threadMap: I have f $f");
my @threadLists = &makeSublistsForThreads($L,$nThr);
#in the event that L is less than $nThr, we reduce the number of threads
$nThr = scalar(@threadLists);
my @threads;
my @ret;
for(0 .. $nThr-1){
#invoke the threads in list context
# push @threads, threads->create({'context' => 'list'}, sub{ my ($L,$f) = @_; print "I have L <@$L> and f $f\n"; return (map{ &f($_) } @{$L}) }, ($threadLists[$_],$f));
push @threads, threads->create({'context' => 'list'}, sub{ my ($L) = @_; print "I have L <@$L> and f $f\n"; return (map{ &f($_) } @{$L}) }, ($threadLists[$_]));
}
for(@threads){
#each thread returns its items, so we get them back in order
push @ret, $_->join();
}
return @ret;
}
當我運行這個所謂的 '富' 擁有大約如下腳本:
my @L = (1 .. 5);
my $f = sub{ my ($i) = @_; return 100*$i; };
print "I have f $f\n";
@out = &threadMap("L"=>\@L,"f"=>$f);
&log(1,"I had input <@L> and output <@out>");
my @realOut = map{ &$f($_) } @L;
&log(1,"Output should be <@realOut>");
我得到這樣的輸出:
我有F代碼(0xbf3530)
我有f代碼(0xbf3530)我爲L < 1>和f CODE(0x110f100)
線程1異常終止:未定義子程序&主::˚F在/ U稱爲 /傑米/perl/jdPerlLib.pl線6037
餘爲L < 2>和f CODE異常終止(0x16b3df0)
線程2:未定義子程序&主::˚F在/ U稱爲 /傑米/perl/jdPerlLib.pl線6037
我有大號< 3>和f CODE(0x1a7d7b0)
線程3異常終止:未定義子程序&主::˚F在/u/jamie/perl/jdPerlLib.pl線稱爲
我爲L < 4 >和f CODE(0x1fbb600)
螺紋4異常終止:未定義子程序&主::˚F稱爲 在/u/jamie/perl/jdPerlLib.pl線6037
我爲L < 5>和f代碼(0x7 fd5240b78c0)
螺紋5異常終止:未定義子程序&主::˚F在/u/jamie/perl/jdPerlLib.pl線6037稱爲 。
星期三07月17日10時27分49秒2013:我有輸入< 1 2 3 4 5>和輸出<>
這告訴我,功能參考是恆定的,從foo到頂部我線程映射子程序,但是一旦它被傳遞給線程,它就會被改變並且變得不合時宜。爲什麼是這樣?我可以避免它嗎?
注意,它無法與兩個
#invoke the threads in list context
# push @threads, threads->create({'context' => 'list'}, sub{ my ($L,$f) = @_; print "I have L <@$L> and f $f\n"; return (map{ &f($_) } @{$L}) }, ($threadLists[$_],$f));
push @threads, threads->create({'context' => 'list'}, sub{ my ($L) = @_; print "I have L <@$L> and f $f\n"; return (map{ &f($_) } @{$L}) }, ($threadLists[$_]));
和
#invoke the threads in list context
push @threads, threads->create({'context' => 'list'}, sub{ my ($L,$f) = @_; print "I have L <@$L> and f $f\n"; return (map{ &f($_) } @{$L}) }, ($threadLists[$_],$f));
#push @threads, threads->create({'context' => 'list'}, sub{ my ($L) = @_; print "I have L <@$L> and f $f\n"; return (map{ &f($_) } @{$L}) }, ($threadLists[$_]));
而且,因爲這是我的第一篇到計算器,很清楚我的問題不夠,或過於/不夠詳細?
更新 - 如果我的測試程序「foo」具有以下內容,則它會顯示工作: sub f {$ i)= @_;返回100 * $ i; } my $ f = \&f; 這提示了一個可能的解釋 - perl使匿名子例程引用SOMEWHERE的淺拷貝不在它是否是對'真實'子例程的引用?但我仍然不清楚細節......任何'指針'(har!)? –