سؤال

أواجه مشكلة في التفرع منذ فترة طويلة عملية من بعض التعليمات البرمجية التي تعمل تحت 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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top