multithreading - Passing subroutine references to perl threads -


i trying pass subroutine references perl threads implement threadmap subroutine. in environment have 'roll own' of things; installing new perl packages not option.

also, running perl version 5.10. in work environment, versions of perl > 5.10 not available.

i can pass subroutine references around without trouble. however, once try pass subroutine reference thread, thread not appear understand it.

here proposed threadmap subroutine, comments are, believe, sufficiently explanatory interested question-answerers.

#input: hash keys l (listref), f (function can apply each element of l), , optionally nthreads #default nthreads 50 #divides l sublists each thread, kicks off threads #each thread applies f each element of sublist #and returns result of $f on each item #output: map{ &$f($_) } @{$l}, done threadily sub threadmap{   %arg = @_;   ($l,$f,$nthr) = ($arg{l},$arg{f},$arg{nthreads});   $maxthreads = 50;   if(not defined $nthr or $nthr > $maxthreads){    $nthr = $maxthreads;   }    &log(1,"threadmap: have f $f");    @threadlists = &makesublistsforthreads($l,$nthr);   #in event l less $nthr, reduce number of threads   $nthr = scalar(@threadlists);   @threads;    @ret;   for(0 .. $nthr-1){   #invoke threads in list context   #    push @threads, threads->create({'context' => 'list'}, sub{ ($l,$f) = @_; print "i have l <@$l> , f $f\n"; return (map{ &f($_) } @{$l}) }, ($threadlists[$_],$f) );   push @threads, threads->create({'context' => 'list'}, sub{ ($l) = @_; print "i have l <@$l> , f $f\n"; return (map{ &f($_) } @{$l}) }, ($threadlists[$_]) );   }   for(@threads){   #each thread returns items, them in order       push @ret, $_->join();   }   return @ret; } 

when run script called 'foo' has approximately following:

my @l = (1 .. 5);  $f = sub{ ($i) = @_; return 100*$i; };  print "i have f $f\n";  @out = &threadmap("l"=>\@l,"f"=>$f); &log(1,"i had input <@l> , output <@out>");  @realout = map{ &$f($_) } @l;  &log(1,"output should <@realout>"); 

i output:

i have f code(0xbf3530)

wed jul 17 10:27:49 2013: threadmap: have f code(0xbf3530)

i have l <1> , f code(0x110f100)

thread 1 terminated abnormally: undefined subroutine &main::f called @ /u/jamie /perl/jdperllib.pl line 6037.

i have l <2> , f code(0x16b3df0)

thread 2 terminated abnormally: undefined subroutine &main::f called @ /u/jamie /perl/jdperllib.pl line 6037.

i have l <3> , f code(0x1a7d7b0)

thread 3 terminated abnormally: undefined subroutine &main::f called @ /u/jamie/perl/jdperllib.pl line 6037.

i have l <4> , f code(0x1fbb600)

thread 4 terminated abnormally: undefined subroutine &main::f called @ /u/jamie/perl/jdperllib.pl line 6037.

i have l <5> , f code(0x7fd5240b78c0)

thread 5 terminated abnormally: undefined subroutine &main::f called @ /u/jamie/perl/jdperllib.pl line 6037.

wed jul 17 10:27:49 2013: had input <1 2 3 4 5> , output <>

this tells me function reference constant foo top of threadmap subroutine, once passed threads gets changed , goes haywire. why this? can avoid it?

note fails both

  #invoke threads in list context   #    push @threads, threads->create({'context' => 'list'}, sub{ ($l,$f) = @_; print "i have l <@$l> , f $f\n"; return (map{ &f($_) } @{$l}) }, ($threadlists[$_],$f) );   push @threads, threads->create({'context' => 'list'}, sub{ ($l) = @_; print "i have l <@$l> , f $f\n"; return (map{ &f($_) } @{$l}) }, ($threadlists[$_]) ); 

and

  #invoke threads in list context       push @threads, threads->create({'context' => 'list'}, sub{ ($l,$f) = @_; print "i have l <@$l> , f $f\n"; return (map{ &f($_) } @{$l}) }, ($threadlists[$_],$f) );   #push @threads, threads->create({'context' => 'list'}, sub{ ($l) = @_; print "i have l <@$l> , f $f\n"; return (map{ &f($_) } @{$l}) }, ($threadlists[$_]) ); 

also, first post stackoverflow, question clear enough, or too/insufficiently verbose?

you calling function named "f" inside threadmap:

map{ &f($_) } ... 

which function, error message indicates, not exist.

you mean dereference , invoke coderef instead:

map { $f->($_) } ... 

in update comment, code works because there define sub named "f".

as aside, should not call perl subs ampersand sigil. hold-over syntax perl 4, , has specific semantics in perl 5 never needed when merely want call sub.

calling &f disable prototype handling , can pass along @_ — if behavior doesn't seem useful you, don't use feature. & used when denoting sub per se (e.g., my $coderef = \&f or defined &f) , special goto &f invocations. & dereferences code ref, typically invoke it, operation more conveyed arrow , parentheses: $coderef->().


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -