in reply to Re: Fork Me I need help
in thread Fork Me I need help

You only think your code works. But what's going to happen if two children write at once?

I would use something like:

use warnings 'all'; use strict; use Email::Valid::Loose; use Net::DNS; use Fcntl qw /:flock :seek/; ... setup stuff ... sub check_addresses; open my $bad => "> badmails" or die "Failed to open badmails: $!\ +n"; open my $good => "> goodmails" or die "Failed to open goodmails: $! +\n"; my $chunk_size = int (@adds / 20) + 1; while (@adds) { my @chunk = splice @chunks, 0, $chunk_size; my $pid = fork; die "Failed to fork: $!\n" unless defined $pid; unless ($pid) { check_addresss @chunk; exit; } } 1 until wait () == -1; # Wait till all children have died. exit; sub check_addr { my $address = shift; ... do some test, return 1 if good, 0 if bad ... } sub check_addresses { foreach my $address (@addresses) { my $handle = check_addr ($address) ? $good : $bad; flock $handle, LOCK_EX or die "Flock failed: $!\n"; seek $handle, SEEK_END, 0 or die "Seek failed: $!\n"; print $handle, "$address\n"; flock $handle, LOCK_UN or die "Flock failed: $!\n"; } }

Abigail

Replies are listed 'Best First'.
Re: Fork Me I need help
by neilwatson (Priest) on May 30, 2002 at 20:08 UTC
    I believe you. Clinging to the hope that some of my code is good I tried this using some of your suggestions:

    #!/usr/bin/perl -w #checks for valid email address #usage validemail <file containing email addresses> use warnings; use strict; use Email::Valid::Loose; use Net::DNS; use Parallel::ForkManager; use Fcntl qw/:flock :seek/; my $pm=new Parallel::ForkManager(20); my $resolver=Net::DNS::Resolver->new(); my $addrfile = $ARGV[0]; my ($is_valid, $host, $x, @mx, $add, @adds, $handle); #custom words that make emails invalid to you my @custom = qw( postmaster webmaster ); open (EMAILS, "$addrfile"); while (<EMAILS>){ $_ =~ s/\015//; chomp $_; push @adds, $_; } close (EMAILS); #warning, I will delete existing files open (BADADDR, ">badmails") || die; open (GOODADDR, ">goodmails") || die; foreach $add (@adds){ $pm->start and next; foreach $x (@custom){ if ($add =~ m/$x/){ writebad(); #address is bad $pm->finish; } } #if email is invalid move on if (!defined(Email::Valid::Loose->address($add))){ writebad(); #address is bad $pm->finish; } #if email is valid get domain name $is_valid = Email::Valid::Loose->address($add); if ($is_valid =~ m/\@(.*)$/) { $host = $1; } $is_valid=""; # perform dsn lookup to check domain @mx=mx($resolver, $host); if (@mx) { writegood(); #address is good }else{ writebad(); #address is bad } $pm->finish; } close (GOODADDR); close (BADADDR); 1 until wait () == -1; # Wait till all children have died. exit; sub writegood{ flock GOODADDR, LOCK_EX or die "Flock failed: $!\n"; seek GOODADDR, SEEK_END, 0 or die "Seek failed: $!\n"; print GOODADDR "$add\n"; flock GOODADDR, LOCK_UN or die "unFlock failed: $!\n"; } sub writebad{ flock BADADDR, LOCK_EX or die "Flock failed: $!\n"; seek BADADDR, SEEK_END, 0 or die "Seek failed: $!\n"; print BADADDR "$add\n"; flock BADADDR, LOCK_UN or die "unFlock failed: $!\n"; }

    Alas, now only a couple of blank lines are written to goodmails and badmails. Fork Me!

    Neil Watson
    watson-wilson.ca