وقتی یک Process کارش تموم میشه چه اتفاقی میوفته
تا اینجا با fork و exec و wait و حتی Zombie Process آشنا شدیم
حالا فرض کنید یه Process داریم که کارش رو انجام داده و دیگه کاری برای انجام دادن نداره
مثلا یه برنامه خیلی ساده داریم:
int main() {
printf("Hello");
return 0;
}
وقتی main تموم میشه برنامه هم باید به سیستم عامل بفهمونه که
کار من تموم شده
اینجاست که مفهوم exit وارد داستان میشه
exit دقیقا چیکار میکنه
خیلی ساده بخوایم بگیم
exit
به سیستم عامل میگه این Process دیگه کاری نداره و میخواد اجرای خودش رو تموم کنه
مثلا:
exit(0);
اون عدد 0 معمولا یعنی برنامه با موفقیت تموم شده
یعنی
exit(0)
↓
اجرای موفق
ولی اگه مقدار غیر صفر بدیم معمولا یعنی یه وضعیت دیگه اتفاق افتاده
مثلا یه خطا
البته معنی دقیق اون عدد رو خود برنامه مشخص میکنه
پس قرار نیست Kernel بفهمه عدد 1 دقیقا یعنی چه خطایی
این عدد بیشتر یه اطلاعاتیه که Process به Parent میده
بعد از exit چی میشه
اینجا یه نکته مهم داریم
وقتی Process به exit میرسه دیگه قرار نیست دستورهای معمول برنامه رو ادامه بده
یعنی اجرای برنامه تموم شده
ولی Kernel هنوز باید چندتا کار انجام بده
مثلا منابعی که Process استفاده میکرد باید مدیریت بشن
مثل:
Memory
File Descriptor
منابع مربوط به I O
و اطلاعات مربوط به خود Process
ولی یه نکته خیلی مهم
همه چیز همون لحظه کامل تموم نمیشه
این همون جاییه که Zombie Process دوباره وارد داستان میشه
فرض کنید این وضعیت رو داریم
Parent
│
└──── Child
│
▼
exit()
│
▼
اجرای Child تموم شد
│
▼
Zombie
Child دیگه اجرا نمیشه
CPU
هم دیگه بهش برای اجرای برنامه CPU Time نمیده
ولی یه مقدار اطلاعات مربوط به پایانش هنوز توسط Kernel نگه داشته میشه
چرا
چون Parent باید بتونه بفهمه Child چطوری تموم شده
مثلا Exit Status اون چی بوده
بعد Parent میاد و wait میکنه
Child
│
▼
exit()
│
▼
Zombie
│
▼
Parent calls wait()
│
▼
Exit Status دریافت میشه
│
▼
Reaping
│
▼
Zombie از بین میره
به این مرحله آخر میگیم
Reaping
یعنی Parent وضعیت پایان Child رو میگیره و Kernel دیگه اطلاعات باقی مونده مربوط به اون Child رو لازم نداره
پس یه نکته خیلی مهم رو یادتون باشه
Termination با Reaping یکی نیست
Termination
یعنی Process دیگه اجرا نمیشه
Reaping
یعنی Parent وضعیت پایان Process رو دریافت میکنه و اطلاعات باقی مونده مربوط به اون Process از ساختارهای مدیریت Process جمع میشه
این تفاوت دقیقاً دلیل وجود Zombie Process هست
Exit Status چیه
وقتی یه Process تموم میشه میتونه یه مقدار به عنوان وضعیت پایان خودش داشته باشه
مثلا
exit(0);
یعنی
Exit Status = 0
یا
exit(1);
یعنی
Exit Status = 1
توی Unix و Linux معمولا 0 یعنی همه چیز خوب تموم شده
و مقدارهای غیر صفر معمولا برای وضعیتهای دیگه استفاده میشن
Parent
میتونه این مقدار رو با wait یا waitpid دریافت کنه
حالا کل داستان رو کنار هم بذاریم
تا الان چندتا تکه مهم از چرخه Process رو یاد گرفتیم
Parent
│
fork()
│
▼
Child
│
exec()
│
▼
New Program
│
exit()
│
▼
Zombie
│
wait()
│
▼
Reaped
یعنی اول Parent یه Child میسازه
بعد Child میتونه با exec یه Program جدید رو اجرا کنه
Program کارش رو انجام میده
بعد exit میکنه
Process دیگه اجرا نمیشه
ممکنه برای مدت کوتاهی Zombie بشه
بعد Parent با wait وضعیتش رو میگیره
و در نهایت Child Reap میشه
حالا یه سوال مهم
آیا exit یعنی Process همون لحظه از همه جا پاک میشه؟
نه
اینجا یکی از اون جاهاییه که سیستم عامل یه کم از چیزی که در نگاه اول به نظر میاد پیچیده تره
وقتی Process terminate میشه
دیگه اجرا نمیشه
ولی Kernel ممکنه یه مقدار اطلاعات محدود از اون رو نگه داره
مهمترین دلیلش هم اینه که Parent باید بتونه وضعیت پایان Child رو بفهمه
پس این دوتا رو قاطی نکنید
Termination
↓
Process دیگه اجرا نمیشه
Reaping
↓
Parent
وضعیت Process رو میگیره
↓
اطلاعات باقی مونده جمع میشه
یه نکته دیگه درباره منابع
وقتی Process تموم میشه Kernel منابعی که دیگه لازم نیستن رو Cleanup میکنه