الدرس 7: wait() — حصاد العمليات الأبناء ومنع عمليات Zombie
عندما تنتهي عملية ابن من التنفيذ، تبقى في حالة zombie حتى تستدعي العملية الأب wait(). في NVIDIA، يجب على خوادم inference التي تشغّل عدة worker processes أن تنظّفها باستخدام wait(). تحتفظ عمليات zombie التي تحمل CUDA context بذاكرة VRAM محجوزة حتى تستدعي العملية الأب wait() — وهذا خطأ شائع في خوادم G
عملية zombie تشبه موظفاً قدّم خطاب استقالة، لكن المدير لم يوقّع النموذج بعد. لم يعد يعمل، لكنه ما زال يشغل مكتباً. wait() هي توقيع المدير — عندها فقط يتحرر المكتب (الذاكرة).
- عملية Zombie
- عملية انتهت من التنفيذ (تم استدعاء exit()) لكن سجلها في process table لا يزال موجوداً لأن العملية الأب لم تستدعِ wait(). الحالة Z في ps. لا تستهلك عملية zombie أي CPU لكنها تشغل PID ويمكن أن تحتفظ بموارد GPU.
- wait() / waitpid()
- استدعاءات نظام (syscalls) تنتظر انتهاء عملية ابن وتنظّف سجلها. تنتظر wait() أي ابن، وتنتظر waitpid(pid, &status, 0) ابناً محدداً. يجب استدعاؤها لمنع عمليات zombie.
- WIFEXITED
- ماكرو يتحقق مما إذا كانت عملية ابن قد انتهت بشكل طبيعي (عبر exit/return) وليس بواسطة signal. تُرجع WIFEXITED(status) القيمة true إذا كان الإنهاء طبيعياً.
- WEXITSTATUS
- ماكرو يستخرج رمز الخروج من status الذي أرجعته wait(). تُرجع WEXITSTATUS(status) القيمة المُمرَّرة إلى exit() أو المُعادة من main().
- عملية Orphan
- عملية انتهت عمليتها الأب من التنفيذ قبلها. تعيد الـ kernel إسناد عمليات orphan إلى init (PID 1) التي ستستدعي wait() نيابةً عنها. تختلف عن zombie — عملية orphan تعمل، وعملية zombie انتهت.