انجمن‌های فارسی اوبونتو

کمک و پشتیبانی => راهنماها، نکات و ترفندها => نویسنده: آرمان اسماعیلی در 10 شهریور 1392، 02:48 ب‌ظ

عنوان: کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: آرمان اسماعیلی در 10 شهریور 1392، 02:48 ب‌ظ
یک پردازه چیزی نیست جز نمونه‌ای در حال اجرا شدن از یک برنامه. آن را برنامه‌ی در حال کار نیز تعریف کرده‌اند. ایده‌ی پشت ساختار و روابط پردازه‌ها همان مفهوم کلی سیستم لینوکسی است. در این نوشتار درباره‌ی چرخه‌ی عمر پردازه‌ها و انواع آن‌ها بحث خواهیم نمود و نیم‌نگاهی نیز داریم به مسیری که پردازه‌ها در چرخه‌ی عمرشان طی می‌کنند.

۱. کد؛ برنامه؛ پردازه

بیایید ابتدا تفاوت این سه مفهوم را درک کنیم.

کد: مثال زیر را در نظر بگیرید.
#include <stdio.h>
#include <unistd.h>

int main(void)
{
    printf("\n Hello World\n");
    sleep(10);

    return 0;
}

این چند خط را درون فایلی با نام helloWorld.c ذخیره کرده و به آن گوییم «کد».

برنامه: اگر کد بالا را با استفاده از دستور زیر کامپایل کنیم، فایلی قابل اجرا خواهیم داشت با نام helloWorld.

$ gcc -Wall helloWorld.c -o helloWorld
این فایل اجرایی، یک «برنامه» است.

پردازه: حال برنامه‌ی helloWorld را اجرا می‌کنیم:
$ ./helloWorld

 Hello World

زمانی که فایل اجرایی (یا برنامه) اجرا شد، «پردازه‌»ای متناظر با آن ساخته شده و کدهای ماشین درون برنامه را به کار می‌اندازد. به همین دلیل است که پردازه را به عنوان نمونه‌ای از برنامه می‌شناسند.
برای دیدن مشخصات پردازه‌ی ساخته شده، دستور زیر را وارد کنید.

$ ps -aef | grep hello*
1000      6163  3017  0 18:15 pts/0    00:00:00 ./helloWorld

۲. پردازه‌ی والد و پردازه‌ی فرزند

هر پردازه یک والد دارد و ممکن است فرزند هم داشته باشد. به خروجی دستور ps روی اوبونتوی من توجه کنید:

(http://armanes.ir/wp-content/uploads/2013/07/ps.jpg)

اعداد صحیح ستون‌های دوم و سوم خروجی بالا، نمایانگر شناسه‌ی پردازه و شناسه‌ی پردازه‌ی والد آن است. به آنهایی که با فونت درشت مشخص شده‌اند توجه کنید. زمانی‌که من دستور ps -aef را اجرا کردم، پردازه‌ای با شناسه‌ی 6191 ساخته شد. شناسه‌ی پردازه‌ی والد آن را ببینید که 3079 است. اگر بالاتر و ابتدای خروجی را بنگرید، خواهید دید که 3079 شناسه‌ی پردازه‌ی bash است. پس می‌فهمیم پردازه‌ی bash، والد تمام دستوراتی است که داخلش اجرا می‌شوند.

به همین نحو، حتی پردازه‌هایی که خارج از شل ساخته شده‌اند نیز والد دارند. هیچ گاه خانه‌ای در ستون PPID ‏(parent process ID) دستور ps -aef خالی نمی‌ماند. بنابراین تمام پردازه‌ها، والد مخصوص به خود را دارند.

و اما پردازه‌ی فرزند. هر گاه پردازه‌ای یک پردازه‌ی دیگر بسازد، قبلی والد و دومی فرزند نام می‌گیرند. به لحاظ فنی، پردازه‌های فرزند توسط تابع ()fork موجود در کد ساخته می‌شوند. معمولا زمانی که دستوری را درون شل اجرا می‌کنید، ()fork با دنباله‌ای از توابع ()exec همراه می‌گردد.

پیش از این گفتیم هر پردازه‌ای یک والد دارد. سؤالی که پیش می‌آید این است که چه بر سر فرزندی می‌آید که والدش کشته شده؟ سؤال خوبی است. اما اجازه دهید فعلا آن را همینجا رها کنیم.

۳. پردازه‌ی init

هنگام بوت شدن یک سیستم لینوکسی، اولین چیزی که وارد حافظه می‌شود vmlinuz است که همان فایل اجرایی و فشرده شده‌ی کرنل لینوکس است. نتیجه، ساخته شدن اولین پردازه، یعنی init است. PID آن هست 1 و والد تمام پردازه‌ها در یک سشن لینوکسی است. اگر ساختار درختی پردازه‌ها را در نظر بگیرید، init بالاترین جایگاه را به خود اختصاص داده است. دستور pstree را اجرا کنید. خروجی چنین چیزی خواهد بود:

(http://armanes.ir/wp-content/uploads/2013/07/pstree.jpg)

pstree را پیدا کرده و ساختار کامل والد و فرزندی آن را تا init دنبال کنید.

حال بر می‌گردیم سر و وقت سؤالی که بدون پاسخ رهایش کرده بودیم. درباره‌ی وقایعی که بر سر فرزند زنده‌ای که والدش کشته شده نازل می‌شود. خب، در چنین شرایط مشهود است که پردازه‌ی فرزند یتیم می‌شود. اما اتفاقی که خواهد افتاد این است که پردازه‌ی init سرپرستی آن را قبول می‌کند. پس init، والد جدید فرزندانی می‌شود که والدهایشان terminate شده‌اند.

۴. چرخه‌ی عمر پردازه

در این بخش، به بررسی چرخه‌ی عمر یک پردازه‌ی معمولی لینوکسی پیش از کشته شدن و حذف شدن از جدول پردازه‌های کرنل خواهیم پرداخت.


۵. پردازه‌ی زامبی

(http://armanes.ir/wp-content/uploads/2013/07/zombie-processes-on-linux.jpg)

زامبی، یکی از انواع پردازه‌ها است. شما نمی‌توانید زامبی‌ها را بکشید زیرا آنها همین الآن هم مرده‌اند! درست مانند زامبی‌های واقعی. یک زامبی در اصل بقایای پردازه‌ای کشته شده است که به طور صحیح پاکسازی نشده. برنامه‌ی استاندارد نباید به زامبی‌ها اجازه‌ی عرض اندام بدهد.

هنگامی که یک پردازه می‌میرد، به طور کامل از حافظه حذف نمی‌شود؛ بلکه توصیف‌گر آن درون حافظه باقی می‌ماند. وضعیت پردازه به EXIT_ZOMBIE تغییر یافته و والدش توسط سیگنال SIGCHLD از این واقعه مطلع می‌گردد. اکنون از پردازه‌ی والد انتظار می‌رود اعلان سیستمی ()wait را اجرا کند تا درباره‌ی پردازه‌ی مرده و وضعیت آن، اطلاعات کسب کند. پس از اجرای این اعلان است که پردازه‌ی مرده کاملا از حافظه حذف می‌شود.

این مراحل معمولا خیلی سریع طی می‌شوند و زامبی‌ها روی هم انباشته نمی‌شوند. اما اگر پردازه‌ی والد بطور صحیح برنامه‌نویسی نشده باشد، اعلان ()wait را صادر نکرده و فرزندان زامبی‌اش تا زمان پاکسازی، درون حافظه به انتظار می‌نشینند.
ابزارهایی مانند سیستم مانیتور محیط دسکتاپتان یا دستورات top و ps زامبی‌ها را نشان می دهند.

(http://armanes.ir/wp-content/uploads/2013/07/top.png)

آیا زامبی‌ها خطری هم دارند؟

یک پردازه‌ی زامبی به جز فضایی بسیار کم از حافظه برای نگه داشتن توصیف‌گرش، از هیچ یک از منابع سیستمی استفاده نمی‌کند. اما به هر حال زامبی‌ها نیز همانند دیگر پردازه‌ها، شناسه‌ی پردازه‌ی مخصوص به خود را نگه می‌دارند. یک سیستم لینوکسی با معماری ۳۲ بیت، تعداد محدود ۳۲۷۶۷ شناسه‌ی پردازه را پشتیبانی می‌کند. پس اگر زامبی‌ها با سرعت روی هم انباشته شوند - مثلا اگر وب‌سروری که خوب نوشته نشده، زیر بار بالای درخواست‌ها زامبی تولید کند - ممکن است ذخیره‌ی PIDهای قابل استفاده تمام شده و همگی به پردازه‌های زامبی اختصاص یابند. در چنین شرایطی پردازه‌های دیگر قادر به اجرا شدن نخواهند بود!
البته تعداد کم زامبی‌ها مشکلی ایجاد نکرده تنها بیانگر باگ نرم‌افزاری است.

(http://armanes.ir/wp-content/uploads/2013/07/zombie.png)

رهایی یافتن از دست زامبی‌ها

همانطور که بالاتر به آن اشاره شد، کشتن پردازه‌های زامبی همانند دیگران و با سیگنال SIGKILL ممکن نیست. زیرا آنها مرده‌اند اما زنده‌اند! با این حال، راه‌های کمی برای رهایی یافتن از دست آنها وجود دارد.

یک راه، فرستادن SIGCHLD به پردازه‌ی والد است. این سیگنال به والد می‌گوید وقت آن است اعلان سیستمی ()wait را اجرا کرده و فرزندان زامبی‌اش را پاکسازی کند. برای فرستادن این سیگنال از دستور kill استفاده کنید.

kill -s SIGCHLD <pid>
با این حال اگر پردازه‌ی والد درست برنامه‌نویسی نشده باشد، سیگنال SIGCHLD را نادیده می‌گیرد. در این شرایط باید خود پردازه‌ی والد را بکشید. می‌دانیم با کشته شدن پردازه‌ی والد، سرپرستی فرزندان به init داده می‌شود. init خود در فواصل معیین، اعلان سیستمی ()wait را صادر کرده و حساب فرزندان زامبی‌اش را یکسره می‌کند. اکنون دوباره پردازه‌ی والد را راه اندازید. اگر به ساختن فرزندان زامبی ادامه داد، گزارش باگ برایش پر کنید.


این مطلب ترجمه‌ی آزادی بود از:

http://www.thegeekstuff.com/2013/07/linux-process-life-cycle/ (http://www.thegeekstuff.com/2013/07/linux-process-life-cycle/)

http://howtogeek.com/119815/htg-explains-what-is-a-zombie-process-on-linux/ (http://www.howtogeek.com/119815/htg-explains-what-is-a-zombie-process-on-linux/)
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: سالار مقدم در 10 شهریور 1392، 03:05 ب‌ظ
ایول داش آرمان، گل کاشتی!
سی می خونی؟
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: آرمان اسماعیلی در 10 شهریور 1392، 03:17 ب‌ظ
^ نه والا. چیز خاصی نمی‌خونم!
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: MHA152 در 13 شهریور 1392، 12:08 ب‌ظ
خیلی عالی بود خیلی زحمت کشیدید دستتون درد نکنه فقط یک سوالی داشتم در مورد اون بخش کشته شدن والد:اگه فرزند میره زیر مجموعه ی init پس نباید تو کارش وقفه بیافتد دیگه؟یعنی اگه من دستور دانلود فایلی را در ترمینال وارد کردم و ترمینال را بستم بازم فایل دانلود میشه؟
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: سالار مقدم در 13 شهریور 1392، 12:31 ب‌ظ
خیلی عالی بود خیلی زحمت کشیدید دستتون درد نکنه فقط یک سوالی داشتم در مورد اون بخش کشته شدن والد:اگه فرزند میره زیر مجموعه ی init پس نباید تو کارش وقفه بیافتد دیگه؟یعنی اگه من دستور دانلود فایلی را در ترمینال وارد کردم و ترمینال را بستم بازم فایل دانلود میشه؟
نه دیگه دانلود نمیشه، ولی در صورتی که با کنترل زد به پس زمینه نبرده باشیش
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: MHA152 در 13 شهریور 1392، 02:35 ب‌ظ
خیلی عالی بود خیلی زحمت کشیدید دستتون درد نکنه فقط یک سوالی داشتم در مورد اون بخش کشته شدن والد:اگه فرزند میره زیر مجموعه ی init پس نباید تو کارش وقفه بیافتد دیگه؟یعنی اگه من دستور دانلود فایلی را در ترمینال وارد کردم و ترمینال را بستم بازم فایل دانلود میشه؟
نه دیگه دانلود نمیشه، ولی در صورتی که با کنترل زد به پس زمینه نبرده باشیش
منظورتون اینه که هر کد درحال انجامی را میشه با کنترل+z به پس زمینه برد و سپس ترمینال را بست؟
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: سالار مقدم در 13 شهریور 1392، 04:26 ب‌ظ
خیلی عالی بود خیلی زحمت کشیدید دستتون درد نکنه فقط یک سوالی داشتم در مورد اون بخش کشته شدن والد:اگه فرزند میره زیر مجموعه ی init پس نباید تو کارش وقفه بیافتد دیگه؟یعنی اگه من دستور دانلود فایلی را در ترمینال وارد کردم و ترمینال را بستم بازم فایل دانلود میشه؟
نه دیگه دانلود نمیشه، ولی در صورتی که با کنترل زد به پس زمینه نبرده باشیش
منظورتون اینه که هر کد درحال انجامی را میشه با کنترل+z به پس زمینه برد و سپس ترمینال را بست؟
آره می تونی ببندی یا اینکه باز بزاری و دستورات دیگه ای بزنی، با گزاشتن & اخر هر دستور هم می تونی اینکارو بکنی
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: ali.abry در 13 شهریور 1392، 09:00 ب‌ظ
خیلی عالی بود خیلی زحمت کشیدید دستتون درد نکنه فقط یک سوالی داشتم در مورد اون بخش کشته شدن والد:اگه فرزند میره زیر مجموعه ی init پس نباید تو کارش وقفه بیافتد دیگه؟یعنی اگه من دستور دانلود فایلی را در ترمینال وارد کردم و ترمینال را بستم بازم فایل دانلود میشه؟
نه دیگه دانلود نمیشه، ولی در صورتی که با کنترل زد به پس زمینه نبرده باشیش
منظورتون اینه که هر کد درحال انجامی را میشه با کنترل+z به پس زمینه برد و سپس ترمینال را بست؟
آره می تونی ببندی یا اینکه باز بزاری و دستورات دیگه ای بزنی، با گزاشتن & اخر هر دستور هم می تونی اینکارو بکنی

Ctrl+z با وقتی که & میزاریم اخرش فرق میکنه .
وقتی Ctrl+z میزنیم به پروسس سیگنال 20  میفرسته که باعث میشه پروسس متوقف بشه و بره به پشت صحنه
ولی وقتی & میزاریم مثل وقتی هست که با Ctrl+z پروسس رو متوقف میکنیم و میفرستیم به پشت صحنه و دوباره با دستور bg بهش سیگنال میدیم (عدد 18) که به کارش در پشت صحنه ادامه بده.
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: سالار مقدم در 13 شهریور 1392، 09:25 ب‌ظ
Ctrl+z با وقتی که & میزاریم اخرش فرق میکنه .
وقتی Ctrl+z میزنیم به پروسس سیگنال 20  میفرسته که باعث میشه پروسس متوقف بشه و بره به پشت صحنه
ولی وقتی & میزاریم مثل وقتی هست که با Ctrl+z پروسس رو متوقف میکنیم و میفرستیم به پشت صحنه و دوباره با دستور bg بهش سیگنال میدیم (عدد 18) که به کارش در پشت صحنه ادامه بده.
دمت گرم نمیدونستم !
عنوان: پاسخ : کوتاه درباره‌ی پردازه‌ها و چرخه‌ی عمر آنان
ارسال شده توسط: MHA152 در 18 شهریور 1392، 04:37 ب‌ظ
این mode ها که نوشتید یعنی چی؟