سؤال

أعرف عمليات fork() و wait() و waitpid() و zombie...لقد فهمتهم من خلال قراءة W.ريتشارد ستيفنز وهو كتاب جيد جدا.

إذا لم نستدعي الانتظار () في الوالدين، فسيصبح الطفل زومبي بعد الإنهاء...وهو أمر سيء!

إذا قمنا باستدعاء الانتظار () في الأصل، فسينتظر الوالد حتى ينتهي الطفل، ويتلقى حالة الإنهاء ثم يستمر.يكتب؟

لقد مررت بالعديد من الأمثلة التي تستدعي fork() مرة واحدة ثم تنتظر() في الأصل.

ولكن إذا كان الوالد سينتظر على الإطلاق الطفل ويستمر بعد انتهاء الطفل، فلن يكون هناك تعدد مهام فعلي (من الناحية الفنية نعم هناك عمليتان.ولكن من الناحية المنطقية لا فائدة) فلماذا نسميه fork() هنا؟

كان بإمكاننا كتابة رمز الطفل ثم رمز الوالدين بدلاً من fork() & wait() كعملية واحدة... ألن يكون ذلك أفضل؟

شكرًا!

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

المحلول

في بعض الأحيان، من المفيد أن شوكة() حتى لو كان الوالد سوف يقوم بالحظر على الفور.الحالة الأكثر شيوعًا هي عندما تفعل شيئًا مشابهًا لـ نظام() الاتصال وتنفيذ أمر خارجي وانتظار اكتماله:ستفعل شوكة() + تنفيذي ().(على الرغم من ذلك، في التعليمات البرمجية الحديثة، يجب أن تفكر في استخدام posix_spawn() بدلا من هذا الغرض.)

مع ذلك، انتظر() لا يحتاج إلى منع.يمكنك استخدام الانتظار () مع العلم ونوهانج لجمع رمز الخروج من أي عملية مكتملة أو الاستمرار على الفور إذا كانت لا تزال قيد التشغيل.

نصائح أخرى

الكود الذي تكتبه بينهما fork() و waitpid() يعمل في وقت واحد، جنبا إلى جنب مع شوكة الطفل.

ينتظر الوالد حتى ينتهي الطفل، وغالبًا ما يقوم بذلك ببساطة لالتقاط البيانات المقدمة من الطفل ومن ثم يعرضها لوالديه.لنفترض أنك قمت بتشغيل حلقة رئيسية حيث يتم تشغيل المهام كـ "خلفية".على سبيل المثال:

// a simple scheduler
while(1) {
   if(done_task_1) {
      // if done_task_1 is ever to change in the parent memory scope,
      // parent must know the exit status of its child fork.
      // otherwise there is no way to enter this if sentance, ever
      collect_data_1();
      run_task_1 = 0;
   }
   else if(run_task_1 == 1) {
      // iterate instructions for a sec
      posix_kill(pid_task_1, SIGCONT);
      sleep(1);
      posix_kill(pid_task_1, SIGSTOP);

   } 

   if(done_task_2) {
      collect_data_2();
      run_task_2 = 0;
   }
   else if(run_task_2 == 1) {
      // iterate instructions for a sec
      posix_kill(pid_task_2, SIGCONT);
      sleep(1);
      posix_kill(pid_task_2, SIGSTOP);

   } 
   if(run_task_1 == 0 && run_task_2 == 0) {
       break;
   }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top