كيف يمكنني تفرع العمليات الخلفية من البرنامج النصي Perl CGI على نظام التشغيل Windows؟

StackOverflow https://stackoverflow.com/questions/45792

سؤال

لقد واجهت بعض المشاكل في تفرع العمليات من برنامج Perl CGI النصي عند التشغيل على نظام التشغيل Windows.يبدو أن المشكلة الرئيسية هي أن "الشوكة" تتم محاكاتها عند التشغيل على النوافذ، ولا يبدو أنها تنشئ عملية جديدة (مجرد سلسلة رسائل أخرى في العملية الحالية).وهذا يعني أن خوادم الويب (مثل IIS) التي تنتظر انتهاء العملية، تستمر في الانتظار حتى تنتهي عملية "الخلفية".

هل هناك طريقة للتخلص من عملية الخلفية من برنامج نصي CGI ضمن Windows؟والأفضل من ذلك، هل هناك وظيفة واحدة يمكنني الاتصال بها والتي ستقوم بذلك بطريقة عبر الأنظمة الأساسية؟

(ولجعل الحياة أكثر صعوبة، أود حقًا أن أجد طريقة جيدة لإعادة توجيه مخرجات العمليات المتشعبة إلى ملف في نفس الوقت).

هل كانت مفيدة؟

المحلول

إذا كنت تريد القيام بذلك بطريقة مستقلة عن النظام الأساسي، بروك::الخلفية ربما هو أفضل وسيلة.

نصائح أخرى

يستخدم Win32::العملية->إنشاء مع المعلمة DETACHED_PROCESS

بيرلفورك:

يوفر Perl كلمة رئيسية شوكة () تتوافق مع مكالمة نظام UNIX التي تحمل نفس الاسم.على معظم الأنظمة الأساسية التي تشبه UNIX حيث تتوفر استدعاء نظام Fork () ، تدعوها Perl's Fork () ببساطة.

على بعض الأنظمة الأساسية مثل Windows حيث لا تتوفر استدعاء نظام Fork () ، يمكن بناء Perl لمحاكاة Fork () على مستوى المترجم المترجم.على الرغم من أن المحاكاة مصممة لتكون متوافقة قدر الإمكان مع الشوكة الحقيقية () على مستوى برنامج PERL ، فهناك بعض الاختلافات المهمة التي تنبع من حقيقة أن جميع "عمليات" الأطفال "المزيفة" التي تم إنشاؤها بهذه الطريقة على الهواء مباشرة في نفس العملية الحقيقية فيما يتعلق بنظام التشغيل.

لقد وجدت مشاكل حقيقية مع fork() على نظام التشغيل Windows، خاصة عند التعامل مع كائنات Win32 في لغة Perl.وبالتالي، إذا كان الأمر يتعلق بنظام التشغيل Windows، فإنني أوصي حقًا بإلقاء نظرة على مكتبة Thread داخل Perl.

أستخدم هذا لتحقيق تأثير جيد في قبول أكثر من اتصال واحد في نفس الوقت على مواقع الويب التي تستخدم IIS، ثم استخدام المزيد من سلاسل الرسائل لتنفيذ نصوص برمجية مختلفة في وقت واحد.

هذا السؤال قديم جدًا والإجابة المقبولة صحيحة.ومع ذلك، لقد قمت للتو بتشغيل هذا الأمر، واعتقدت أنني سأضيف المزيد من التفاصيل حول كيفية إنجازه لأي شخص يحتاج إليه.

الكود التالي موجود في برنامج Perl CGI كبير جدًا.يقوم هذا الروتين الفرعي الخاص بإنشاء التذاكر في أنظمة التذاكر المتعددة، ثم يستخدم أرقام التذاكر المرتجعة لإجراء مكالمة تلقائية عبر خدمات Twilio.تستغرق المكالمة بعض الوقت، ولم أرغب في أن يضطر مستخدمو CGI إلى الانتظار حتى تنتهي المكالمة لرؤية مخرجات طلبهم.ومن أجل ذلك قمت بما يلي:

  (All the CGI code that is standard stuff.  Calls the subroutine needed, and then)

  my $randnum = int(rand(100000));
  my $callcmd = $progdir_path . "/aoff-caller.pl --uniqueid $uuid --region $region --ticketid $ticketid";
  my $daemon = Proc::Daemon->new(
    work_dir     => $progdir_path,
    child_STDOUT => $tmpdir_path . '/stdout.txt',
    child_STDERR => $tmpdir_path . '/stderr.txt',
    pid_file     => $tmpdir_path . '/' . $randnum . '-pid.txt',
    exec_command => $callcmd,
  );
  my $pid = $daemon->Init();

  exit 0;

  (kill CGI at the appropriate place)

أنا متأكد من أن الرقم العشوائي الذي تم إنشاؤه وإرفاقه برقم التعريف الشخصي مبالغ فيه، لكن ليس لدي أي اهتمام بخلق مشكلات يمكن تجنبها بسهولة شديدة.نأمل أن يساعد هذا الشخص الذي يتطلع إلى القيام بنفس الشيء.تذكر أن تضيف use Proc::Daemon في الجزء العلوي من البرنامج النصي الخاص بك، اعكس الكود وقم بالتغيير إلى مسارات وأسماء برنامجك، ويجب أن تكون جاهزًا للمضي قدمًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top