The first mod_perl generation has only a single
PerlInterpreter, which is constructed by the
parent process, then inherited across the forks to child processes.
mod_perl 2.0 has a configurable number of
PerlInterpreters and two classes of interpreters,
parent and clone. A parent is like in mod_perl
1.0, where the main interpreter created at startup time compiles any
preloaded Perl code. A clone is created from the
parent using the Perl API perl_clone( ) function.
At request time, parent interpreters are used only for making more
clones, as the clones are the interpreters that actually handle
requests. Care is taken by Perl to copy only mutable data, which
means that no runtime locking is required and read-only data such as
the syntax tree is shared from the parent, which should reduce the
overall mod_perl memory footprint.
The interpreters pool mechanism has been abstracted into an API known
as tipool (thread item pool). This pool,
currently used to manage a pool of PerlInterpreter
objects, can be used to manage any data structure in which you wish
to have a smaller number of items than the number of configured
threads.
It's important to notice that the Perl ithreads
implementation ensures that Perl code is thread-safe, at least with
respect to the Apache threads in which it is running. However, it
does not ensure that functions and extensions that call into
third-party C/C++ libraries are thread-safe. In the case of
non-thread-safe extensions, if it is not possible to fix those
routines, care needs to be taken to serialize calls into such
functions (either at the XS or Perl level). See Perl
5.8.0's perlthrtut manpage.
Note that while Perl data is thread-private unless explicitly shared
and threads themselves are separate execution threads, the threads
can affect process-scope state, affecting all the threads. For
example, if one thread does chdir("/tmp"), the
current working directory of all threads is now
/tmp. While each thread can correct its current
working directory by storing the original value, there are functions
whose process-scope changes cannot be undone. For example,
chroot( ) changes the root directory of all
threads, and this change is not reversible. Refer to the
perlthrtut manpage for more information.