Re: Command-line PHP script CPU usage goes sky-high, stays there--why?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks Jim. Several good points here that I will look into. I've already moved the include() bits into function calls. (That's simple thing I should have corrected long ago.) The socket areas though I'm less sure about how to adjust, since networking programming isn't something I grok naturally.

On 10-Dec-07, at 9:57 PM, Jim Lucas wrote:

René Fournier wrote:
FWIW, here's the stripped-down skeleton of the server:
As always, constructive criticism is very welcome.
<?php
$socket = stream_socket_server("tcp://127.0.0.1:9876", $errno, $errstr);
if ($socket) {
        $master[] = $socket;
    $read = $master;
    $write = $master;               while (1) {
            $read = $master;
        $write = $master;


The follow part, I think, is where your problem is.


This line tells the system to wait 1 second and then continue, whether you have an inbound connection or not.
        $mod_fd = stream_select($read, $_w = NULL, $_e = NULL, 1);

Then here you are testing for success or failure of the last call.

        if ($mod_fd === FALSE) {
            break;
            }

Problem, if you don't have a connection, then the will fail constantly.
once every second X (times) the number of connections you have...

But my understanding from the docs (where I used one of the examples as a template for the script) socket is that it could/would only fail on startup, that is if it can't perform stream_select() because it's unable to bind to with stream_socket_server(), or am I wrong?: "If the call fails, it will return FALSE and if the optional errno and errstr arguments are present they will be set to indicate the actual system level error that occurred in the system-level socket(), bind(), and listen() calls. If the value returned in errno is 0 and the function returned FALSE, it is an indication that the error occurred before the bind() call. This is most likely due to a problem initializing the socket. Note that the errno and errstr arguments will always be passed by reference." (http://www.php.net/manual/en/ function.stream-socket-server.php)

In other wrongs, mod_fd can't return FALSE once the socket_server has been created and bound to the specified IP... right?




                   for ($i = 0; $i < $mod_fd; ++$i) {
            if ($read[$i] === $socket) {        // NEW SOCKET
                $conn = stream_socket_accept($socket, 900);
                $master[] = $conn;
                $key_num = array_search($conn, $master, TRUE);
                               } else {
                $sock_data = fread($read[$i], 32768);
if (strlen($sock_data) === 0) { // CONNECTION GONE $key_to_del = array_search($read [$i], $master, TRUE); fclose($read[$i]); unset ($master[$key_to_del]); } elseif ($sock_data === FALSE) { // CONNECTION BROKEN $key_to_del = array_search ($read[$i], $master, TRUE);
                    fclose($read[$i]);
                    unset($master[$key_to_del]);
} else { // READ INCOMING DATA

Here, you are not removing the successful connections from $master, so it keeps growing.... on and on...

But only until the connection closes, or no longer blocks (goes away), in which case the program fcloses that socket and removes it from master[].



As for the includes, well, I would turn them into function calls and then have a different function for the different ways you want the program to react.

Yes, I did that. It helps a bit with CPU.


                    // include (somefiles);
                    // include (somefiles);
                    // include (somefiles);
                    // [ ... ]
                    }
                }
            }
        }
    }
?>

I didn't see anything about your DB connections. Are those located in the includes?

Just at header.inc, once.


How long, on average, does your processing of the incoming data take? Because, to me, it looks like you might have a blocking problem with the in-coming connections. If the initial connection takes too long, then the following connections might be getting blocked. You might want to look into pcntl_* functions to do forking if you need it.

The processing is pretty quick. I don't think that's a bottleneck. It basically just inserts the data into MySQL, not much processing actually.



--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux