كيف يمكنني شوكة بشكل صحيح مع mod_perl2?
سؤال
أواجه مشكلة في التفرع منذ فترة طويلة عملية من بعض التعليمات البرمجية التي تعمل تحت mod_perl2.
كل شيء يعمل معظمها ، ولكن يبدو أن متشعب عملية عقد فتح مقابض أباتشي logfiles - هذا يعني أباتشي لن إعادة تشغيل أثناء عملية التشغيل (أحصل على 'فشل في فتح logfiles' الرسالة).
هنا مدونة أنا باستخدام:
use POSIX; # required for setsid
# Do not wait for child processes to complete
$SIG{CHLD} = 'IGNORE';
# fork (and make sure we did!)
defined (my $kid = fork) or die "Cannot fork: $!\n";
if ($kid) {
return (1, $kid);
}else {
# chdir to /, stops the process from preventing an unmount
chdir '/' or die "Can't chdir to /: $!";
# dump our STDIN and STDOUT handles
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
# redirect for logging
open STDERR, '>', $log_filename or die "Can't write to log: $!";
# Prevent locking to apache process
setsid or die "Can't start a new session: $!";
# execute the command
exec( $cmd, @args );
die "Failed to exec";
}
مرة أخرى في mod_perl1 أيام ، أذكر باستخدام $r->cleanup_for_exec
لحل هذه المشكلة, ولكن لا يبدو أن تكون معتمدة من تحت mod_perl2.(تحرير: على ما يبدو إنه لا يطلب أي أكثر..)
أي نصائح حول كيفية بشكل صحيح بدء العملية طويلة الامد من mod_perl2 دون هذه المشاكل سيكون موضع تقدير كبير!
المحلول
ربما كنت ترغب في قراءة هذا مناقشة.يبدو أنك لا شوكة على mod_perl إلا إذا كنت تعرف كيفية تحضير الأشياء.لديك لاستخدام وحدة مثل Apache2::SubProcess
نصائح أخرى
حاول إغلاق الخاص بك ستدين/STDOUT مقابض قبل شوكة.
في بلدي (سابقا mod_perl الآن FCGI) رمز لدي في "آخر" بند "if ($kpid)",
close STDIN;
close STDOUT;
close STDERR;
setsid();
أيضا لأسباب نسيت فورا شوكة مرة أخرى ، ثم أن الطفل إعادة فتح STDIN ، المعياري ، STDERR.
بحيث يبدو مثل:
$SIG{CHLD} = 'IGNORE';
# This should flush stdout.
my $ofh = select(STDOUT);$| = 1;select $ofh;
my $kpid = fork;
if ($kpid)
{
# Parent process
waitpid($kpid, 0);
}
else
{
close STDIN;
close STDOUT;
close STDERR;
setsid();
my $gpid = fork;
if (!$gpid)
{
open(STDIN, "</dev/null") ;#or print DEBUG2 "can't redirect stdin\n";
open(STDOUT, ">/dev/null") ;#or print DEBUG2 "can't redirect stdout\n";
open(STDERR, ">/dev/null") ;#or print DEBUG2 "can't redirect stderr\n";
# Child process
exec($pgm, @execargs) ;# or print DEBUG2 "exec failed\n";
}
exit 0;
}