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

Hello, I am using a WHILE(1) that is used by the script to poll a ip address/port continously but we do not like that it is using 100% CPU. Is ther anthing that can be done as this script needs to poll 24/7. We were thinking about using the sleep but were afraid we would lose transactions. Does nyone have any ideas on modifying the script to not use 100% CPU%? Here is the part of the script with the WHILE:
while (1) { # Continously Listening on Port for connections my ($rh_set) = IO::Select->select($read_set, undef, undef, 0); foreach $rh (@$rh_set) { print "Process each handle...\n"; print "Main socket connection..\n"; $ns = $rh->accept(); $read_set->add($ns); }else{ print "Ordinary socket, read...\n"; my $bytecount = sysread($rh, $buf, 1024); $iroam_req_type = substr($buf,0,8); if($buf) { print " *** BEGIN PROCESSING CALL ***"; print "Iroam transaction received:\n"; print "$buf\n"; if ($iroam_req_type =~ /FindMin/){ $find_min_request_rec = $buf; }elsif ($iroam_req_type =~ /PriceCal/){ $price_call_rec = $buf; } pass_transaction_to_iroam_package(); print "Sending Response....\n"; $rh->send($iroam_response_rec); }else { print "Iroam client closed socket..\n"; $read_set->remove($rh); close($rh); } } }

Replies are listed 'Best First'.
Re: While(1) using 100% CPU
by ikegami (Patriarch) on Apr 03, 2008 at 21:06 UTC

    You're telling select to timeout immediately, causing it to be called over and over again. You presumably wanted to tell it to never timeout. As documented, this is done by not specifying a timeout.

    IO::Select->select($read_set, undef, undef, 0)
    should be
    IO::Select->select($read_set, undef, undef) (documented)
    or
    IO::Select->select($read_set, undef, undef, undef) (undocumented)

    By the way, since the write and error objects aren't specified, you can simply use can_read.

    $read_set->can_read()

Re: While(1) using 100% CPU
by samtregar (Abbot) on Apr 03, 2008 at 17:40 UTC
    Easily fixed, just change that 0 in your select() call to something larger. The larger you make it the less CPU time your code will take while it waits for something to do. You won't miss any transactions because select() will wake up as soon as there's something to read.

    You might also look at IO::Poll - rumor has it that it performs better than select.

    -sam

Re: While(1) using 100% CPU
by mr_mischief (Monsignor) on Apr 03, 2008 at 17:35 UTC
    If you can stand a shorter delay than what sleep() supports, there is select(). There's also Time::HiRes.

    However, you're already using IO::Select->select() which I would think, being based on select(), would give you all you need. You could try setting the timeout to something other than 0, like 0.25 even undef if you only want it to return when there's something to act upon.

Re: While(1) using 100% CPU
by NetWallah (Canon) on Apr 03, 2008 at 17:40 UTC
    Try increasing the TIMEOUT from 0 to say 0.25 .

    select ( READ, WRITE, EXCEPTION [, TIMEOUT ] )

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re: While(1) using 100% CPU
by locked_user sundialsvc4 (Abbot) on Apr 08, 2008 at 21:26 UTC

    Simply use an ordinary timed wait on the port: you're not going to lose transactions.

    When any process “busy waits,” it consumes entire time-slices... unproductively. That's precisely opposite from what you want to be doing:   your computer has other, more-important things to do. It has no way to know whether a very-busy process is doing something “useful.”