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

Hello I'm doing a perl smtp sender that uses Parallel::ForkManager,Net::SMTP,MIME::Base64 and Authen::SASL and I have 30 smtp servers and send to 10 addresses simultaneously using splice.When I start the script all is fine but after some time,like 5 minutes or so,the script causes very high cpu loading even over 100%.I just want to know if there is a way around this.

My machine is "Debian GNU/Linux 4.0 \n \l" with two "model name : Genuine Intel(R) CPU 2140 @ 1.60GHz" and "2067452" RAM and my code is this :
#!/usr/bin/perl require MIME::Base64; require Authen::SASL; use Net::SMTP; use Parallel::ForkManager; print "From address->email@domain.com: "; $from = <>; chomp $from; print "From name->Name: "; $fromname = <>; chomp $fromname; print "Subject->This is a test: "; $subject = <>; chomp $subject; print "Mail file->mail.txt: "; $mail = <>; chomp $mail; print "Addresses file->addresses.txt: "; $addresses = <>; chomp $addresses; print "SMTP file->smtp.txt: "; $smtpfile = <>; chomp $smtpfile; print "Max parallel SMTP->30: "; $max = <>; chomp $max; print "Max addresses per SMTP->10: "; $maxaddresses = <>; chomp $maxaddresses; open(MAIL, $mail); @boday = <MAIL>; close(MAIL); $body = ""; foreach $pew (@boday) { $body.="$pew"; } open(my $y, "<", "$smtpfile") or die "$smtpfile: $!"; my @y = <$y>; close($y); chomp @y; open(INFO, $addresses); @addresses = <INFO>; close(INFO); $" = ","; chomp @addresses; $pm = new Parallel::ForkManager($max); foreach $target (@addresses) { chomp $target; @tenaddresses = splice(@addresses, 0, $maxaddresses); $index_y++; $index_y = 0 if($index_y > $#y); my $pid = $pm->start and next; my $value = "$_$y[$index_y]"; @info = split(/ /, $value); $server = $info[0]; $username = $info[1]; $pass = $info[2]; print "[+] Sending with $server to @tenaddresses | "; $connection = Net::SMTP->new($server, Timeout => 10, Debug => 0, ); if (!defined($connection) || !($connection)) { print ("Error at connecting. Skipping.\n"); } else { $connection->auth($username, $pass); $connection->mail($from); $connection->recipient(@tenaddresses); $connection->data; $connection->datasend("From: $fromname <$from>\r\n"); $connection->datasend("Content-Type: text/html \r\n"); $connection->datasend("Subject: $subject\r\n"); $connection->datasend("\r\n"); $connection->datasend("$body\r\n"); $connection->datasend("\r\n"); $connection->dataend(); $connection->quit; print ("Done.\n"); } $pm->finish; }

Replies are listed 'Best First'.
Re: Net::SMTP High Cpu Load
by locked_user sundialsvc4 (Abbot) on Mar 10, 2009 at 13:15 UTC

    Could it simply be that you're congested up-stream? Do you know that whomever you are sending this volume of information to, can actually take it? Do you know that the “pipe” that gets you there, can actually sustain the load?

    Intuitively, I suspect that you might have far too many processes working on this, and perhaps, too many servers.

    Dividing-up a computer's time does not increase it. Deploying a multiple number of processes does not accelerate any chore except to the extent that I/O overlap can be meaningfully exploited. If all of those processes are doing the same thing against the same resource, and if that resource is not subject to inherent physical speed-factors (such as the rotational and/or seek times of a disk drive), it is quite probable that they are actually getting in one another's way.

    Furthermore, if this be so, then the speed-degredation will not be linear. Instead, it will reach a “thrash point,” at which point the performance graph will take a sharp knee-bend ... straight up, i.e. horribly bad. This may well be exactly what is happening to you.

    (In the olden days, when disk drives were large machines that sat on the raised floor, we'd call it “going into Maytag® mode,” because the drives looked and sounded like a washing-machine on the “spin” cycle. One of them actually moved far enough to drop one leg into a hole in the raised floor. Ugh.)

Re: Net::SMTP High Cpu Load
by codeacrobat (Chaplain) on Mar 10, 2009 at 13:15 UTC
Re: Net::SMTP High Cpu Load
by ig (Vicar) on Mar 11, 2009 at 09:05 UTC

    Consider the following advice from perlsyn, regarding foreach loops:

    If any part of LIST is an array, "foreach" will get very confused if you add or remove elements within the loop body, for example with "splice". So don’t do that.