Professional Web Applications Themes

Proc::Fork - PERL Beginners

I receive an error while running this script. It goes an gets a list of IP addresses that are on the network, then collects SNMP data from them. There are 8 modems available. 10.100.254.255 10.100.254.252 10.100.255.252 10.100.253.255 10.100.255.254 10.100.255.253 10.100.255.251 10.100.254.254 10.100.254.253 When the script is run I see this output: #./fork-control-test.pl 10.100.254.255 10.100.254.252 10.100.255.252 10.100.253.255 10.100.255.254 10.100.255.253 10.100.255.251 10.100.254.254 10.100.254.253 0.0.0.0 # 00:08:0E:E5:C6:AC 00:E0:6F:21:6F:34 00:E0:6F:38:54:06 Can't locate object method "writer. via package "IO::Pipe::End" at ../fork-control-test.pl line 92. 00:E0:6F:14:AD:A2 Can't locate object method "writer" via package "IO::Pipe::End" at ../fork-control-test.pl line 92. Error Received: Can't locate object method "writer" via package ...

  1. #1

    Default Proc::Fork

    I receive an error while running this script. It goes an gets a list of
    IP addresses that are on the network, then collects SNMP data from them.

    There are 8 modems available.

    10.100.254.255
    10.100.254.252
    10.100.255.252
    10.100.253.255
    10.100.255.254
    10.100.255.253
    10.100.255.251
    10.100.254.254
    10.100.254.253

    When the script is run I see this output:

    #./fork-control-test.pl
    10.100.254.255
    10.100.254.252
    10.100.255.252
    10.100.253.255
    10.100.255.254
    10.100.255.253
    10.100.255.251
    10.100.254.254
    10.100.254.253
    0.0.0.0
    #
    00:08:0E:E5:C6:AC
    00:E0:6F:21:6F:34
    00:E0:6F:38:54:06
    Can't locate object method "writer. via package "IO::Pipe::End" at
    ../fork-control-test.pl line 92.
    00:E0:6F:14:AD:A2
    Can't locate object method "writer" via package "IO::Pipe::End" at
    ../fork-control-test.pl line 92.

    Error Received: Can't locate object method "writer" via package
    "IO::Pipe::End" at ./fork-control-test.pl line 91, <GEN0> line 1.

    Line 91 of fork-control-test is 

    If the child process is something simple like print $data, it works great.
    As soon as I put something in that requires some processing, filehandles, or network traffic, I get these errors.

    Does anyone see issues? What does the error actually mean?

    -Mike



    The entire script is below.


    use strict;
    use Proc::Fork;
    use IO::Pipe;
    use Net::SNMP;
    use SNMP;
    my $num_children = 4; # How many children we'll create
    my children; # Store connections to them
    $SIG{CHLD} = 'IGNORE'; # Don't worry about reaping zombies
    # Spawn off some children
    for my $num (1..$num_children)
    {
    # Create a pipe for parent-child communication
    my $pipe = new IO::Pipe;

    # Child simply echoes data it receives, until EOF
    child
    {
    $pipe->reader;
    my $data;
    while ($data = <$pipe>)
    {
    chomp $data;
    my $com='notshown';
    my (%VALUES,tmp,macparts,$SESSION);

    $SESSION = new SNMP::Session( DestHost => $data,
    Community => $com,
    Version => 2,
    Timeout => 1000000,
    Retries => 3,
    UseSprintValue => 1) ||
    die("Can't connect to modem $data");
    $VALUES{'ip_address'} = $data;
    $VALUES{'sysDescr'} =
    $SESSION->get(".1.3.6.1.2.1.1.1.0");
    if(!$VALUES{'sysDescr'}) { return; }
    exit -11 if (! $VALUES{'sysDescr'});
    $VALUES{'mac_address'} =
    $SESSION->get(".1.3.6.1.2.1.17.1.1.0");
    $VALUES{'level_up'} =
    $SESSION->get(".1.3.6.1.2.1.10.127.1.2.2.1.3.2");
    $VALUES{'level_down'} =
    $SESSION->get(".1.3.6.1.2.1.10.127.1.1.1.1.6.3");
    $VALUES{'sn_ratio'} =
    $SESSION->get(".1.3.6.1.2.1.10.127.1.1.4.1.5.3");
    $VALUES{'sw_ver'} =
    $SESSION->get(".1.3.6.1.2.1.69.1.3.5.0");
    $VALUES{'config_file'} =
    $SESSION->get(".1.3.6.1.2.1.69.1.4.5.0");
    $VALUES{'firmware_ver'} =
    $SESSION->get(".1.3.6.1.2.1.69.1.3.2.0");
    $VALUES{'date'} = `date +%Y-%m-%d\\ %H:%M:%S`;
    chomp $VALUES{'date'};
    macparts=split(/\"/, $VALUES{'mac_address'});
    $VALUES{'mac_address'} = $macparts[1];
    chomp $VALUES{'mac_address'};
    $VALUES{'mac_address'} =~ s/\ /:/g;
    $VALUES{'mac_address'} =~ s/:$//;

    my cf=split(/\"/, $VALUES{'config_file'});
    chomp($cf[1]);
    $VALUES{'config_file'} = $cf[1];

    my fw=split(/\"/, $VALUES{'sw_ver'});
    $VALUES{'sw_ver'} = $fw[1];

    if (! $VALUES{'sn_ratio'}) {
    $VALUES{'sn_ratio'} = 0;
    }
    if (! $VALUES{'firmware_ver'}) {
    $VALUES{'firmware_ver'} = 'Undefined';
    }

    # Sanitize some vars.
    foreach my $l ('level_up', 'level_down', 'sn_ratio') {
    if ($VALUES{$l} !~ m/^[0-9\.\-]+$/){
    tmp=split(/\ /, $VALUES{$l});
    $VALUES{$l}=$tmp[1];
    }
    }
    open(MODEMDATA, ">modemdata/$VALUES{'ip_address'}.txt");
    print MODEMDATA "$VALUES{'mac_address'},";
    print STDERR $VALUES{'mac_address'};
    print MODEMDATA "$VALUES{'ip_address'},";
    print MODEMDATA "$VALUES{'level_up'},";
    print MODEMDATA "$VALUES{'level_down'},";
    print MODEMDATA "$VALUES{'sn_ratio'},";
    print MODEMDATA "$VALUES{'date'},";
    print MODEMDATA "$VALUES{'config_file'},";
    print MODEMDATA "$VALUES{'firmware_ver'},";
    print MODEMDATA "$VALUES{'sysDescr'},";
    print MODEMDATA "$VALUES{'sw_ver'}\n";
    close(MODEMDATA);
    }
    exit;
    };

    # Parent here
    $pipe->writer;
    push children, $pipe;
    }

    my($res_ip,cmip,$key,%res_ip,$ip,%VALUES,tmp,ma cparts,$SESSION);
    my $oid_ip=".1.3.6.1.2.1.10.127.1.3.3.1.3";
    my ($session,$error_line) = Net::SNMP->session(
    -hostname => '192.168.200.1',
    -version => 2,
    -community => 'notshown'
    );
    if (!defined($res_ip=$session->get_table($oid_ip))) {
    printf(" %s\n", $session->error);
    $error_line=$session->error;
    $session->close;
    next;
    }
    my $ipc=0;
    foreach $key (sort keys %$res_ip) {
    $cmip[$ipc]=$$res_ip{$key};
    $ipc++;
    }
    $cmtstime=time();

    # Send some data to the kids

    foreach $ip (cmip){
    print "$ip\n";
    if($ip ne '0.0.0.0'){
    # pick a child at random
    my $num = int rand $num_children;
    my $child = $children[$num];
    print $child "$ip\n";
    }
    }
    exit;


    Michael Guest

  2. #2

    Default Proc::Fork

    I receive an error while running this script. It goes an gets a list of
    IP addresses that are on the network, then collects SNMP data from them.

    There are 8 modems available.

    10.100.254.255
    10.100.254.252
    10.100.255.252
    10.100.253.255
    10.100.255.254
    10.100.255.253
    10.100.255.251
    10.100.254.254
    10.100.254.253

    When the script is run I see this output:

    #./fork-control-test.pl
    10.100.254.255
    10.100.254.252
    10.100.255.252
    10.100.253.255
    10.100.255.254
    10.100.255.253
    10.100.255.251
    10.100.254.254
    10.100.254.253
    0.0.0.0
    #
    00:08:0E:E5:C6:AC
    00:E0:6F:21:6F:34
    00:E0:6F:38:54:06
    Can't locate object method "writer. via package "IO::Pipe::End" at
    ../fork-control-test.pl line 92.
    00:E0:6F:14:AD:A2
    Can't locate object method "writer" via package "IO::Pipe::End" at
    ../fork-control-test.pl line 92.

    Error Received: Can't locate object method "writer" via package
    "IO::Pipe::End" at ./fork-control-test.pl line 91, <GEN0> line 1.

    Line 91 of fork-control-test is 

    If the child process is something simple like print $data, it works
    great.
    As soon as I put something in that requires some processing,
    filehandles, or network traffic, I get these errors.

    Does anyone see issues? What does the error actually mean?

    -Mike



    The entire script is below.


    use strict;
    use Proc::Fork;
    use IO::Pipe;
    use Net::SNMP;
    use SNMP;
    my $num_children = 4; # How many children we'll create
    my children; # Store connections to them
    $SIG{CHLD} = 'IGNORE'; # Don't worry about reaping zombies
    # Spawn off some children
    for my $num (1..$num_children)
    {
    # Create a pipe for parent-child communication
    my $pipe = new IO::Pipe;

    # Child simply echoes data it receives, until EOF
    child
    {
    $pipe->reader;
    my $data;
    while ($data = <$pipe>)
    {
    chomp $data;
    my $com='notshown';
    my (%VALUES,tmp,macparts,$SESSION);

    $SESSION = new SNMP::Session( DestHost => $data,
    Community => $com,
    Version => 2,
    Timeout => 1000000,
    Retries => 3,
    UseSprintValue => 1) ||
    die("Can't connect to modem $data");
    $VALUES{'ip_address'} = $data;
    $VALUES{'sysDescr'} =
    $SESSION->get(".1.3.6.1.2.1.1.1.0");
    if(!$VALUES{'sysDescr'}) { return; }
    exit -11 if (! $VALUES{'sysDescr'});
    $VALUES{'mac_address'} =
    $SESSION->get(".1.3.6.1.2.1.17.1.1.0");
    $VALUES{'level_up'} =
    $SESSION->get(".1.3.6.1.2.1.10.127.1.2.2.1.3.2");
    $VALUES{'level_down'} =
    $SESSION->get(".1.3.6.1.2.1.10.127.1.1.1.1.6.3");
    $VALUES{'sn_ratio'} =
    $SESSION->get(".1.3.6.1.2.1.10.127.1.1.4.1.5.3");
    $VALUES{'sw_ver'} =
    $SESSION->get(".1.3.6.1.2.1.69.1.3.5.0");
    $VALUES{'config_file'} =
    $SESSION->get(".1.3.6.1.2.1.69.1.4.5.0");
    $VALUES{'firmware_ver'} =
    $SESSION->get(".1.3.6.1.2.1.69.1.3.2.0");
    $VALUES{'date'} = `date +%Y-%m-%d\\ %H:%M:%S`;
    chomp $VALUES{'date'};
    macparts=split(/\"/, $VALUES{'mac_address'});
    $VALUES{'mac_address'} = $macparts[1];
    chomp $VALUES{'mac_address'};
    $VALUES{'mac_address'} =~ s/\ /:/g;
    $VALUES{'mac_address'} =~ s/:$//;

    my cf=split(/\"/, $VALUES{'config_file'});
    chomp($cf[1]);
    $VALUES{'config_file'} = $cf[1];

    my fw=split(/\"/, $VALUES{'sw_ver'});
    $VALUES{'sw_ver'} = $fw[1];

    if (! $VALUES{'sn_ratio'}) {
    $VALUES{'sn_ratio'} = 0;
    }
    if (! $VALUES{'firmware_ver'}) {
    $VALUES{'firmware_ver'} = 'Undefined';
    }

    # Sanitize some vars.
    foreach my $l ('level_up', 'level_down', 'sn_ratio') {
    if ($VALUES{$l} !~ m/^[0-9\.\-]+$/){
    tmp=split(/\ /, $VALUES{$l});
    $VALUES{$l}=$tmp[1];
    }
    }
    open(MODEMDATA, ">modemdata/$VALUES{'ip_address'}.txt");
    print MODEMDATA "$VALUES{'mac_address'},";
    print STDERR $VALUES{'mac_address'};
    print MODEMDATA "$VALUES{'ip_address'},";
    print MODEMDATA "$VALUES{'level_up'},";
    print MODEMDATA "$VALUES{'level_down'},";
    print MODEMDATA "$VALUES{'sn_ratio'},";
    print MODEMDATA "$VALUES{'date'},";
    print MODEMDATA "$VALUES{'config_file'},";
    print MODEMDATA "$VALUES{'firmware_ver'},";
    print MODEMDATA "$VALUES{'sysDescr'},";
    print MODEMDATA "$VALUES{'sw_ver'}\n";
    close(MODEMDATA);
    }
    exit;
    };

    # Parent here
    $pipe->writer;
    push children, $pipe;
    }

    my($res_ip,cmip,$key,%res_ip,$ip,%VALUES,tmp,ma cparts,$SESSION);
    my $oid_ip=".1.3.6.1.2.1.10.127.1.3.3.1.3";
    my ($session,$error_line) = Net::SNMP->session(
    -hostname => '192.168.200.1',
    -version => 2,
    -community => 'notshown'
    );
    if (!defined($res_ip=$session->get_table($oid_ip))) {
    printf(" %s\n", $session->error);
    $error_line=$session->error;
    $session->close;
    next;
    }
    my $ipc=0;
    foreach $key (sort keys %$res_ip) {
    $cmip[$ipc]=$$res_ip{$key};
    $ipc++;
    }
    $cmtstime=time();

    # Send some data to the kids

    foreach $ip (cmip){
    print "$ip\n";
    if($ip ne '0.0.0.0'){
    # pick a child at random
    my $num = int rand $num_children;
    my $child = $children[$num];
    print $child "$ip\n";
    }
    }
    exit;


    Michael Guest

  3. #3

    Default RE: Proc::Fork

    Michael Gargiullo wrote: 
    >
    > If the child process is something simple like print $data, it works
    > great.
    > As soon as I put something in that requires some processing,
    > filehandles, or network traffic, I get these errors.
    >
    > Does anyone see issues? What does the error actually mean?[/ref]

    The error is saying that $pipe has been reblessed into an IO::Pipe::End,
    which will be true if you've already called reader() or writer() on the
    IO::Pipe object. I can't see anything obvious in your script that would
    cause this however, unless the child { } block is somehow running off past
    the end where you have the exit; statement.

    Note that you really don't want to just pick children at random to fire off
    messages to. You want to have some communication between the children and
    the parents so the child can tell the parent when he's ready to receive the
    next message. That way you keep all your children busy. This can be done by
    using another pipe for the children to write their child number back to or
    similar.
    Bob Guest

  4. #4

    Default RE: Proc::Fork

    Bob Showalter wrote: 

    Here's an example using a pipe for the children to signal the parent:

    #!/usr/bin/perl

    use strict;

    use IO::Pipe;
    use IO::Handle;
    use Proc::Fork;

    my $num_children = 3; # no. of children
    my $control = IO::Pipe->new; # control channel

    # Spawn off some children
    my child;
    for my $num (1 .. $num_children) {
    my $data = IO::Pipe->new; # data channel

    child {
    $data->reader;
    $control->writer;
    $control->autoflush(1);

    print $control "$num\n";
    while (<$data>) {
    chomp;
    print "Child $num: received [$_]\n";
    sleep rand(3) + 1;
    print $control "$num\n";
    }
    exit;
    };

    # parent
    $data->writer;
    $data->autoflush(1);
    push child, $data;
    next;

    }

    # send data to children as they become ready
    my $n = 1;
    $control->reader;
    while(<$control>) {
    chomp;
    my $fh = $child[$_ - 1];
    print $fh "Data $n\n";
    $n++;
    last if $n > 20;
    }

    # reap the children
    close $_ for child;
    1 while wait > 0;
    Bob Guest

Similar Threads

  1. fork (UDP) server
    By Flex in forum UNIX Programming
    Replies: 10
    Last Post: January 20th, 12:20 AM
  2. CGI Script Fork
    By James Taylor in forum PERL Beginners
    Replies: 2
    Last Post: November 22nd, 08:23 AM
  3. Pipe/Fork revisited - 4 proc program
    By PJ in forum UNIX Programming
    Replies: 6
    Last Post: September 26th, 09:16 AM
  4. fork not available?
    By walter@mwsewall.com in forum Ruby
    Replies: 22
    Last Post: September 23rd, 02:56 PM
  5. memory and fork
    By Peteris in forum UNIX Programming
    Replies: 3
    Last Post: September 22nd, 10:12 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139