http://qs1969.pair.com?node_id=1200869

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

CentOS 6.9, mod_perl 2.08, Apache 2.2, my script:
#!/usr/bin/perl print "Content-type: text/html; charset=UTF-8\n\n" ; ++$i ; print "i=$i, $ENV{MOD_PERL}, pid is $$<br>\n" ; exit ;

When I run it repeatedly(F5) using browser( http://www.xx...x.com/cgi-bin/test.cgi )

I got:

i=1, mod_perl/2.0.8, pid is 17578
i=2, mod_perl/2.0.8, pid is 17578
i=3, mod_perl/2.0.8, pid is 17578
i=1, mod_perl/2.0.8, pid is 467
i=2, mod_perl/2.0.8, pid is 467
i=4, mod_perl/2.0.8, pid is 17578
i=1, mod_perl/2.0.8, pid is 24789
i=2, mod_perl/2.0.8, pid is 24789
i=3, mod_perl/2.0.8, pid is 24789
i=5, mod_perl/2.0.8, pid is 17578
i=3, mod_perl/2.0.8, pid is 467
i=1, mod_perl/2.0.8, pid is 24378
i=2, mod_perl/2.0.8, pid is 24378
i=1, mod_perl/2.0.8, pid is 2742
i=2, mod_perl/2.0.8, pid is 2742

The script re-compiled every time for new pid ( i=1 ) .

Is it something wrong with server/mod_perl or with my knowledge in mod_perl?
Is it Apache recompile a script for every new child/process?

Please help understand this.

Thank you, Alex

Replies are listed 'Best First'.
Re: mod_perl children process
by LanX (Saint) on Oct 07, 2017 at 00:39 UTC
    Well it's not recompiled every time, but probably your Apache is operating with multiple sub processes handling the requests.

    And each such process must have its own mod-Perl version of your cgi.

    I'd expect that the max number of such processes is a matter of configuration.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

      Thank you. Any experienced people can help? Why Apache recompile script every time?
        Every child gets its own copy as designed . there is no problems to solve
Re: mod_perl children process
by talexb (Chancellor) on Oct 07, 2017 at 19:43 UTC

    Running a script under mod_perl can be a confusing world to learn about.

    The point of mod_perl is that it's a Perl interpreter baked into the Apache web server. Instead of having to run the script (and therefore Perl) every time there's a web request, mod_perl loads the script in a ready-to-run form, so as to improve performance.

    Falling back to food analogies (because they're easy for me), it's a bit like a diner making up a batch of pancake batter and having the griddle hot, so that when a customer shows up, the batter can go right onto the hot grill, and pancakes are up five minutes later. The alternative would be to make individual batches of batter for each customer who orders pancakes. I think you can imagine that's not as efficient.

    Your experimental results show that Apache is dispatching a request to a variety of kids (diner kitchens), identified by pid. Each request is served (from that kitchen), showing a monotonically increasing count (pancake order count). You should be aware that there's a configuration parameter in the Apache config called something like MaxRequests. When a kid has maxed out its number of requests (that kitchen ran out of batter), it's terminated and a new kid is created (the kitchen makes up a new batch of batter).

    Are you just seeing how it all works, or is there some issue that remains a mystery to you? mod_perl has been around for quite a while, but these days I'd guess it's now classified as old technology. :)

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

Re: mod_perl children process
by CountZero (Bishop) on Oct 08, 2017 at 11:44 UTC
    You have seen for yourself how confusing it is to use global variables in a mod_perl script. You never can predict *which* instance of that global variable will be used.

    It is a good practice to only use lexical "my" variables or if you must use global variables, explicitly initialize them to a known value.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
      Why is a my variable in file scope any better?
Re: mod_perl children process
by afoken (Chancellor) on Oct 07, 2017 at 13:23 UTC
      wrong! :P!
Re: mod_perl children process
by sundialsvc4 (Abbot) on Oct 08, 2017 at 20:38 UTC

    It is, in fact, working as designed.   Let’s sort your list by PID to see if we can thereby discern what is actually happening:

    i=1, mod_perl/2.0.8, pid is 17578 i=2, mod_perl/2.0.8, pid is 17578 i=3, mod_perl/2.0.8, pid is 17578 i=4, mod_perl/2.0.8, pid is 17578 i=5, mod_perl/2.0.8, pid is 17578 i=1, mod_perl/2.0.8, pid is 467 i=2, mod_perl/2.0.8, pid is 467 i=3, mod_perl/2.0.8, pid is 467 i=1, mod_perl/2.0.8, pid is 24789 i=2, mod_perl/2.0.8, pid is 24789 i=3, mod_perl/2.0.8, pid is 24789 i=1, mod_perl/2.0.8, pid is 24378 i=2, mod_perl/2.0.8, pid is 24378 i=1, mod_perl/2.0.8, pid is 2742 i=2, mod_perl/2.0.8, pid is 2742

    We plainly see from this that Apache is running your process using five child-processes, and that the requests are being handled by a per-process Perl instance that has not disappeared (since $i is incrementing), so we know that mod_perl is doing its job.   (Your program is not “being recompiled each time.”)   We also observe that each process is an independent instance, each owning its own independent Perl interpreter context, each with its own distinct and unrelated notion of what $i is.

      Let’s sort your list by PID

      I cannot guess the sorting mechanism which results in (17578, 467, 24789, 24378, 2742) being a sorted sequence. Perhaps you could enlighten me?

        It's the order of the first appearance of each PID in the OP's output.

        So, more like de-interleaving than sorting.

      Why Apache start compile new process if few of them already exists?
      I have heavy scripts where perl load many libraries and I see Apache re-load and recompile whole code every few requests.

        From Re: mpm-worker + mod_perl2 settings meaning

        If all running interpreters are in use, mod_perl will clone new interpreters to handle the request, up until this number of interpreters is reached. when PerlInterpMax is reached, mod_perl will block (via COND_WAIT()) until one becomes available (signaled via COND_SIGNAL()). Default value: 5