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.