A friend of mine seems to think he'd like to be able to ping roughly 1,000 hosts every minute, parse the data, and store current ping times into a database. He asked me for help with the "ping 1,000 hosts every minute" part, and we came up with a massively forked ping server.

The prototype concept is that a list of hosts is stored in a text file. A perl script reads in the hosts list, splits it up among a given number of forked processes, and each process gets to work on pinging. All results are appending into a results file for now.

In essence, I seem to be having trouble coding a fork routine that lives within a loop. Everything grows exponentially. For instance, a file with 10 hosts in it ends up with 212 lines in the result file - the 10 hosts are pinged a total of 212 times. I envisioned that once is enough ;)

My question is, how can I create a variable number of child processes, each chewing on a portion of the data? My code fails at that.

So here's my code. It works great, but not to spec. It is also really bad code, may have blatant errors in implementation, and may be poorly structured. It certainly has not evolved to the point where it waits for child processes to end - a very bad habit, I'm sure. My excuse is that I'm trying (and failing) to prove a concept. My apologies are offered in advance.

#!/usr/bin/perl -w use strict; my @hosts = <>; # list of hosts to ping my $depth = 5; # number of children my $size = 800; # packet size my @pid; # store child pids here open (OUT, ">>results"); for (0..$depth - 1) { $pid[$_] = fork; if ($pid[$_]) { print "$_\n"; # for debugging } else { foreach my $host (splice(@hosts, $_ * (scalar @hosts)/$depth, ($_ ++ 1) * (scalar @hosts)/$depth)) { chomp $host; my @result = `ping -c 1 -s $size $host`; $result[1] =~ s/^.*=//mg; # strip the data down to $result[1] =~ s/ ms.*$//mg; # decimal miliseconds print OUT "$host\t$result[1]"; } } } close OUT;
Here's some characteristics of the output:
su-2.04# ./pingfork.pl testping  | sort | uniq -c
  16 0
  16 1
  16 2
  16 3
  16 4
su-2.04# cat results | wc -l
     212

In reply to A plethora of forks by ginseng

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.