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";
    }
}

Reply via email to