I'm hoping this is the right list, I'm trying to use threads and Net::ping.
Is it unreasonable to try to call ping from multiple threads at once
and expect it to work?
I'll include my short demostration code, below. I tried using p->close()
and/or undef($p), doing Net::Ping->new inside and outside the while loop,
udp, tcp, and icmp pings. All either hang, segfault, some threads
will die, or other strange results like:
Constant subroutine Socket::PF_INET redefined at (eval 2) line 1 thread 2.
Attempt to free unreferenced scalar at /opt/pkg/perl-5.7.0/lib/5.7.0/Net/Ping.pm line
278 thread 4.
Should I just give up on this idea, or does anyone have a suggestion?
This is btw for a piece of code that will scan our subnet for
"up" hosts, collect MAC addresses, and ssh_public_keys and populate
a backend database, and notify the admins of various changes in the network.
Threads seem like a perfect match for this kind of thing, doing multiple
high latency blocking operations in parallel, with nice clean code.
Oh, and of course:
[root@germ pkg]# /opt/pkg/perl-5.7.0/bin/perl -v
This is perl, v5.7.0 built for i686-linux-thread
[root@germ /root]# cat t2.pl
#!/opt/pkg/perl-5.7.0/bin/perl -w
use strict;
use Thread;
use Thread::Queue;
use Net::Ping;
my $stream = new Thread::Queue;
for my $i ( 3 .. 254) {
$stream->enqueue($i);
}
my $domain="169.237.99";
my $maxthreads=4;
for (my $i =0; $i<$maxthreads; $i++)
{
my $kid = new Thread(\&scanhost,$stream,$domain);
$stream->enqueue(undef); # make sure you have one undefine for each thread
}
sub scanhost {
my ($upstream,$domain) = @_;
while (my $num = $upstream->dequeue) {
my $ip=$domain.".".$num;
my $tid=Thread->self->tid();
print "pinging $ip in thread $tid\n";
my $p = Net::Ping->new("icmp");
my $ret=$p->ping($ip,1);
p->close();
undef($p);
print "pung $ip got $ret, I am thread $tid\n";
}
}