in reply to Forking and sharing variables
I added Data::Dumper just for easily displaying the data of our multi dimensional hash %mxs. And I added 'strict' as every good human should :)use strict; use POSIX; use IPC::Shareable; use Net::DNS; use Data::Dumper; $|=1; my $glue = 'data'; my %options = ( create => 'yes', destroy => 'yes', ); my %mxs; my $knot = tie %mxs, 'IPC::Shareable', $glue, { %options } or die "server: tie failed\n"; my @urls = <>; my %hash; for (@urls) { chomp; my ($username, $domain) = split (/\@/); push (@{$hash{$domain}}, $_); }; my $PREFORK = 25; # number of children to maintain my @doms = keys %hash;
First since we want each hash key to be an array (to get rid of the split/join junk) it seems we have to create the anon arrays in the parent. I always got fatal errors if I tried to do it from the child. I am not saying it can't be done, because I dont know ... but I couldn't figure out how to do it.# define the anon arrays here instead of in the child foreach(@doms) { $mxs{$_} = []; } for( 1..$PREFORK ) { last unless @doms > 0; my $url = shift @doms; child( $url ) if !fork(); } wait(); # wait till one dies; my $kid; { if( @doms > 0 ) { my $url = shift @doms; child( $url ) if !fork(); } $kid = wait(); redo unless $kid == -1; } print Data::Dumper->Dump([\%mxs]); exit;
This code is similar to yours, just a trimmed a bit. First we open up the shared memory segment,then call the mx function with the passed in URL. The list result of that is mapped to get out the data we want, and the list returned from map is pushed on the end of the anonymous array for our url in the mxs hash.sub child { my $url = shift; my $glue = 'data'; my %options = ( create => 'no', destroy => 'no', ); my %mxs; my $knot = tie %mxs, 'IPC::Shareable', $glue, { %options } or die "client: tie failed\n"; $knot->shlock; push( @{$mxs{$url}}, map { $_->exchange } mx($url)); $knot->shunlock; exit; }
use strict; use POSIX; use IPC::Shareable; use Net::DNS; use Data::Dumper; $|=1; my $glue = 'data'; my %options = ( create => 'yes', destroy => 'yes', ); my %mxs; my $knot = tie %mxs, 'IPC::Shareable', $glue, { %options } or die "server: tie failed\n"; my @urls = <>; my %hash; for (@urls) { chomp; my ($username, $domain) = split (/\@/); push (@{$hash{$domain}}, $_); }; my $PREFORK = 25; # number of children to maintain my @doms = keys %hash; # define the anon arrays here instead of in the child foreach(@doms) { $mxs{$_} = []; } for( 1..$PREFORK ) { last unless @doms > 0; my $url = shift @doms; child( $url ) if !fork(); } wait(); # wait till one dies; my $kid; { if( @doms > 0 ) { my $url = shift @doms; child( $url ) if !fork(); } $kid = wait(); redo unless $kid == -1; } print Data::Dumper->Dump([\%mxs]); exit; sub child { my $url = shift; my $glue = 'data'; my %options = ( create => 'no', destroy => 'no', ); my %mxs; my $knot = tie %mxs, 'IPC::Shareable', $glue, { %options } or die "client: tie failed\n"; $knot->shlock; push( @{$mxs{$url}}, map { $_->exchange } mx($url)); $knot->shunlock; exit; }
|
|---|