Second question about childs. I not fully understand, how childs work.

In a little bit more details :

When you start Apache, one single process is started.
That's what you can call the "main" Apache.
It reads and checks the configuration, and bombs out if anything is wrong.
If nothing is wrong, it will then "fork" a number of "children" Apache.
That initial number is set in your configuration file.
The "main" Apache continues to live, and it is that one that is "listening" on port 80.

Each of the children is identical, and they can all handle any request.
Each child contains the full configuration of Apache, all the add-on modules etc.. If you are using mod_perl, then each of these children also contains its own copy of mod_perl and of the perl interpreter. Don't forget this.

When a request comes into Apache (the main one), it looks to see which of his children has nothing to do at the moment, and gives the request to that one for processing. If there are no children free, the main Apache may decide to start a new one. That is also defined in the configuration (MaxChild). If there are too many free children, the main Apache may decide to kill some (to save memory etc..). In other words, the main Apache does not handle requests, it just gives work to his children and controls what they are doing and how long they live. It's terrible and immoral, but that's the way it works.

Each child may handle many requests. How many before it dies, depends on another configuration parameter : MaxRequestsPerChild. If this is set to 0, it stays alive "forever" (or until the main Apache decides to kill it). Which specific requests a child will handle, is rather unpredictable : it depends on which child the main Apache gives the next request. (This is not entirely true, but we'll leave that for later).

Now the one selected child handle this one request that he received from his main Apache "papa". If it is a request that involves mod_perl, you have to be careful, because the perl interpreter that is started by mod_perl in this child, remains "alive" as long as this child itself lives, and it does "remember" some things from one request to the next.

For example, that's what makes it fast : the first time it runs one cgi-bin script, it will compile it and keep the resulting compiled code in memory. The next time a request comes to this same Apache child for the same script, it will not need to compile it again, but it will re-use the compiled version. If the request goes to another child, then that one will also compile the script and keep it in memory, because it does not know about the other child. For example, if the script is big, and if there are 15 Apache children, and you call the same script 20 times, it is possible that the first 15 calls will be slow, and then the last 5 times it will be very fast. That is because each child may get one request, and they all have to first compile the script. But at the second time, they don't have to anymore.

There is a danger to this : for some types of variables in your script, perl will remember the last value you put in it, and the next time the script runs in the same child, it will start with that same value. So make sure that all variables that you use, are initialised properly when you start the script.
In other words, write :
my $var = 0;
instead of
my $var;

Note : each Apache child is a totally separate process, and each of these processes has its own memory and its own perl interpreter. So you can in principle NOT "communicate" between one cgi-bin script and the other (or between two consecutive runs of the same script), because you never know in which Apache child your next request is going to run. And variables are NOT shared between different requests, even of the same script, except as indicated above.

Now, if you are very careful, and if you know exactly what you are doing, and if you know exactly how to do it, you might be able, within the same Apache child, to initialise a variable once, and leave it to that same value so that the next time a script runs in the same Apache child, it will find that same value already initialised.

But re-read the previous paragraph 3 times, making sure you understand all the if's. Because if you do this without understanding all those ifs, you will create errors that are very nasty and very difficult to find.

All the above is clearly explained in the mod_perl on-line documentation, but it never hurts to repeat it.




Reply via email to