1

hello all,

i am getting the following error when i am trying to run my 1st Perl script:

[id=0 @ 0] : IP address "3.3.3.3" corresponds to device "core". 
Thread 1 terminated abnormally: Not a CODE reference at ./dev_ithread.pl line 23.
[id=0 @ 1] : IP address "5.5.5.5" corresponds to device "border". 
Thread 2 terminated abnormally: Not a CODE reference at ./dev_ithread.pl line 23.

and here is what i have written so far:

#!/usr/bin/perl

use	strict ;
use	warnings ;
use	diagnostics ;
use	threads ;
use	Config ;

$Config{useithreads} || die("\n---> Please recompile Perl with \<ithreads\> included. \n") ;


# IP parameterization of network elements.
my %device_ip = ( 
			"core" => "3.3.3.3",
			"border" => "5.5.5.5",		
		) ;

# Initialize devices' pool of threads.
my $index = 0 ;
my @device_thread = () ;
while( my ($key, $value) = each %device_ip )	
{ 
	push( @device_thread, threads->new(\&thread_job($key, $device_ip{$key}, $index))->join ) ;	$index = $index+1 ;
}

# Worker thread subroutine.
sub thread_job
{
	my ($device, $ip, $index) = @_ ;

	my $ithread = threads->tid() ;
	print "[id=$ithread @ $index] : IP address \"$ip\" corresponds to device \"$device\". \n" ;
}

i would be thankful, if someone could help me overcome this problem. thank you.

Comments
With code and error message, excellent!
3
Contributors
2
Replies
5
Views
5 Years
Discussion Span
Last Post by erezschatz
0

I don't know about threads and my perl is not built for threads but I can illustrate the problem by the following:

#!/usr/bin/perl
use strict;
use warnings;
use 5.010;

#When you follow the sub name with arguments in parentheses
#the sub runs first and returns a scalar value,
#which the backslash makes into a scalar reference.
say ref(\&example(1, 2, 3));#See? We have a SCALAR reference, not a CODE ref

say ref(\&example);#Now we have a CODE reference.

sub example{
    my ($arg1, $arg2, $arg3) = @_; #Do something with arguments, if any
    return 'example sub executed successfully';
}
1

The threads->new() method (actually threads->create()) accepts a "coderef" which is a reference to a method, and a list of parameters that are passed to the coderef:

threads->new(\&thread_job, $key, $device_ip{$key}, $index)

if you use () after the coderef then perl will a: invoke the method, then b: return a reference to the returned value:

sub code {
    my ($param, $other_param) = @_;
    return $param.$other_param;
}

my $coderef = \&code;
my $noref = \&code("hello ", "world\n");

print "$noref is ". ${$noref};
print "$coderef is " . $coderef->("goodbye ", "baseball\n");

• [barvazon:~] erez $ perl foo
SCALAR(0x8eec818) is hello world
CODE(0x8f076b0) is goodbye baseball

References are a bit tricky to grok at first, but once you wrap your head around references, your perl will automagically leap forward.

Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.