שיעור 7: wait() — קציר תהליכי ילד ומניעת Zombie
כשתהליך ילד מסיים לרוץ, הוא נשאר ב-zombie state עד שתהליך האב קורא ל-wait(). ב-NVIDIA, שרתי inference שמפעילים worker processes מרובים חייבים לנקות אותם עם wait(). תהליכי zombie עם CUDA context מחזיקים VRAM עד שהאב קורא ל-wait() — זה bug נפוץ בשרתי GPU production.
zombie process הוא כמו עובד שהגיש פיטורים בכתב, אבל המנהל לא חתם על הטופס. הוא לא עובד יותר, אבל עדיין תופס שולחן. wait() הוא החתימה של המנהל — רק אז השולחן (הזיכרון) משתחרר.
- תהליך Zombie
- תהליך שסיים לרוץ (exit() נקרא) אבל רשומת ה-process table שלו עדיין קיימת כי האב לא קרא ל-wait(). מצב Z ב-ps. תהליך zombie לא צורך CPU אבל תופס PID ויכול להחזיק משאבי GPU.
- wait() / waitpid()
- syscalls שמחכים לסיום תהליך ילד ומנקים את רשומתו. wait() מחכה לכל ילד, waitpid(pid, &status, 0) מחכה לילד ספציפי. חייבים לקרוא לזה כדי למנוע zombies.
- WIFEXITED
- מאקרו שבודק אם תהליך ילד הסתיים בצורה תקינה (exit/return) ולא ע"י signal. WIFEXITED(status) מחזיר true אם הסיום היה תקין.
- WEXITSTATUS
- מאקרו שמחלץ את קוד היציאה מה-status שהחזיר wait(). WEXITSTATUS(status) מחזיר את הערך שהועבר ל-exit() או return ב-main().
- תהליך Orphan
- תהליך שתהליך האב שלו סיים לרוץ לפניו. הקרנל מאמץ orphan processes ל-init (PID 1) שיקרא ל-wait() עבורם. שונה מzombie — orphan רץ, zombie סיים.