hiradhu has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I'm testing 1-to-1, many-to-one and many-to-many scenarios in SendMail. Meaning, using SendMail modules I need to send mails in this manner using SMTP.


1. One person simultaneously send mail to many ppl - I can use multiple recipient - So I can do this

2. Many to one - I dont know how to many multiple From (around 100000) addresses sending mail to one single To using Fork function.

3. Many to Many - meaning many ppl (say 5000 From) sending mails simultaneously To 5000 ppl using sendmail and fork.

I found Fork, but exactly not sure how to use it. Attached find my code so far i have written. Pls suggest someother better alternative to Fork if any .. The SendMail function works fine.
#!/usr/bin/perl use SendMail; # get the commandline args - FromUserNo, ToUserNo from command my $fromUserNo = $ARGV[0]; my $toUserNo = $ARGV[1]; #setup To and From lists #Build recipient address based on ToUser my $myToUser = "TestTo"; my @ToUser; for( my $i = 1; $i <= $toUserNo; $i++){ $myToUser = "$myToUser"."$i\@xx.yy.com".";"; $myToUser = "TestTo"; } push(@ToUser,$myToUser); #Build Sender address based on FromUser my $myFromUser = "TestFrom"; my @FromUser; for( my $i = 1; $i <= $fromUserNo; $i++){ $myFromUser = "$myFromUser"."$i\@abc.com".";"; $myFromUser = "TestFrom"; } push(@FromUser,$myFromUser); #rules mail server my $server = "xx.yy.com"; $sm = new SendMail($server); #One person sending to multiple receipient at once #for (1..10){ my $pid = fork(); if (not defined $pid) { print "resources avilable, \n"; } elsif ($pid == 0) { $sm->From("test1 <test1\@abc.com>"); $sm->Subject("test"); $sm->To("Rules <rules\@xx.yy.com>"); $sm->setMailBody("test data"); my $attachfile = "C:\\attachmentfile.txt"; $sm->Attach($attachfile); # Check if the mail sent successfully or not. if ($sm->sendMail() != 0) { print $sm->{'error'}."\n"; exit -1; } # Mail sent successfully. print "Mail sent\n\n"; # End child exit(0); } else { print "IM THE PARENT\n"; waitpid($pid,0); } #}

Replies are listed 'Best First'.
Re: Mail::SendMail and fork
by cdarke (Prior) on Apr 01, 2009 at 08:21 UTC
    On UNIX, process creation is done using the kernel C interface fork (some also have vfork). The fork function creates an (almost) exact copy of the parent process, and after the fork the same code runs in both parent and child. Running another program in the child is common, and this is usually done using one of the exec family of functions to replace the current program with another.

    In Perl, you can use fork in exactly the same way. Usually it is used to run an asynchronous process, that is when you don't want to wait for the child to complete. In your code you are waiting for the child to complete, which rather defeats the object. You don't have to wait at once in the parent, you can defer the wait until after all your child processes have started, see the doc for waitpid.

    A couple of things to watch. First, on most UNIXs, when a child process ends it wants to tell the parent its exit code, so it waits until that has been collected, usually through waitpid or by handling the SIGCHLD signal. So if you never do that then the child cannot die, and you end up with a zombie. Second, when the parent exits it will send each child process a SIGHUP signal, which, by default, will kill the child. So make sure you wait until all the children have finished.
      Thanks for the reply. i missed to mention that I'm running perl in Windows. Moreover will this fork handle more than 10k processes at once?!!!

        fork is a bad idea on Windows, and it's a bad idea on any system to try to fork 10000 processes at once. Take a look at Parallel::ForkManager or a simple thread-based solution that runs (say) 5 or 10 worker threads and feeds them from a queue.