فصل ۱۰ – فرایندها
مقدمه
هر دستور یا برنامهای که در محیط خط فرمان اجرا میکنیم، در قالب «فرایند» زنده میشود.
شناخت سازوکار فرایندها به ما امکان میدهد درک کنیم سیستم چگونه منابع را مدیریت میکند،
چطور برنامهها با هم تعامل دارند و چگونه میتوانیم اجرای آنها را زیر نظر گرفته یا کنترل کنیم.
در این فصل میآموزیم:
- فرایند چیست و چگونه از یک «برنامه» متمایز میشود.
- چه رابطهای میان فرایندهای پدر و فرزند برقرار است و نقش نشستها و پوستهها چیست.
- چگونه با ابزارهایی مانند
ps،topوpstreeفرایندهای در حال اجرا را مشاهده و پایش کنیم. - مفهوم «پیشزمینه» و «پسزمینه» در پوسته چیست و چطور با
jobs،bgوfgآنها را مدیریت کنیم. - سیگنالها چه نقشی در پایان دادن یا کنترل فرایندها دارند و چگونه با
kill،killallو میانبرهای صفحهکلید از آنها بهره ببریم.
فرایند چیست؟
در اصطلاح سیستمعامل، برنامه تنها یک مجموعهٔ ایستا از دستورالعملها و دادهها روی دیسک است؛
اما هنگامی که این برنامه بارگذاری و اجرا میشود، هستهٔ سیستمعامل نمونهای پویا به نام فرایند میسازد.
هر فرایند اطلاعاتی از جمله شناسهٔ یکتا (PID)، فضای آدرس حافظه، دستهٔ فایلهای باز، متغیرهای محیطی و وضعیت اجرایی خود را نگه میدارد.
هر بار که یک برنامه را دوباره اجرا میکنیم، حتی اگر از همان فایل باشد، فرایند تازهای ایجاد میشود.
فرایندها میتوانند فرزندهایی بسازند؛ به عنوان مثال، پوسته وقتی دستور جدیدی اجرا میکند، یک فرزند میسازد که برنامهٔ درخواستی را اجرا کند.
پوستهٔ اصلی به عنوان «فرایند والد» شناخته میشود و میتواند وضعیت فرزند را پیگیری کند یا منتظر پایان آن بماند.
نشستها، پایانهها و فرایندهای نگهبان
هر بار که وارد پوسته میشویم (مثلاً با باز کردن یک پنجرهٔ ترمینال یا ورود از طریق SSH)، فرایندی به نام پوسته با پایانهای تعاملی گره میخورد.
فرایندهایی که از این پوسته زاده میشوند در یک نشست (session) مشترک قرار میگیرند.
برخی فرایندها مانند سرویسهای سیستمی و «داِمون»ها (daemon) پایانهای متصل ندارند و در پسزمینهٔ سیستم همیشه فعالاند.
در رأس این درخت، معمولاً فرایندی با PID شمارهٔ 1 قرار دارد که در توزیعهای نوین اغلب همان systemd است.
این فرایند به محض راهاندازی هسته آغاز میشود و والد بسیاری از داِمونها و نشستهای کاربری به شمار میرود.
مشاهدهٔ فرایندها با ps
یکی از سادهترین راهها برای مشاهدهٔ فهرست فرایندهای فعال، دستور کلاسیک ps است.
این دستور بسته به گزینههایی که به آن میدهیم، نمایشهای مختلفی ارائه میدهد.
بدون گزینه، ps معمولاً فقط فرایندهای متصل به پایانهٔ جاری را نشان میدهد:
ps
خروجی نمونه:
PID TTY TIME CMD
4342 pts/0 00:00:00 bash
5021 pts/0 00:00:00 ps
برای دیدن تمام فرایندهای مرتبط با نشست فعلی (حتی آنهایی که پایانه ندارند)، از گزینهٔ x استفاده کنید:
ps x
اگر میخواهیم تمام فرایندهای سیستم را همراه با مالک آنها ببینیم، گزینههای a و u را اضافه میکنیم:
ps aux
این نگارش ستونهایی مانند مالک فرایند، درصد استفاده از CPU و حافظه، زمان شروع، وضعیت (STAT) و فرمان کامل را نشان میدهد.
مرتبسازی و فیلتر کردن خروجی
میتوان خروجی ps را با ابزارهای متنی دیگر ترکیب کرد. برای نمونه، فیلتر کردن فرایندهایی که نام آنها شامل "ssh" است:
ps aux | grep ssh
یا مرتبسازی بر اساس مصرف CPU با استفاده از sort:
ps aux --sort=-%cpu | head
گزینهٔ --sort معیارهای متعددی مانند %mem (مصرف حافظه)، pid (شناسهٔ فرایند) یا start_time را میپذیرد.
نمایش درختی با pstree
برای درک بهتر رابطهٔ والد و فرزند، میتوان از pstree بهره برد که ساختار سلسلهمراتبی فرایندها را نشان میدهد:
pstree -p
گزینهٔ -p شناسهٔ فرایندها را کنار نام آنها میگذارد. برخی توزیعها ممکن است لازم باشد بستهٔ pstree را به طور جداگانه نصب کنید.
پایش زنده با top
دستور top نمایی پویا از فرایندهای در حال اجرا ارائه میدهد و هر چند ثانیه بروزرسانی میشود. پس از اجرا، فهرستی از فرایندها به همراه اطلاعاتی دربارهٔ بار CPU، مصرف حافظه، زمان اجرا و وضعیت نمایش داده میشود.
top
کلیدهای میانبر درون top:
P– مرتبسازی بر اساس مصرف CPU.M– مرتبسازی بر اساس مصرف حافظه.T– مرتبسازی بر اساس زمان اجرا.k– ارسال سیگنال به فرایندی با وارد کردن PID.q– خروج از برنامه.
ابزارهای جایگزین مانند htop رابط کاربرپسندتری دارند، اما top تقریباً روی همهٔ سیستمهای یونیکسی در دسترس است.
کار با فرایندهای پیشزمینه و پسزمینه
پوسته به طور معمول هر فرمان را در پیشزمینه اجرا میکند؛ یعنی کنترل پایانه را تا پایان کار در اختیار دارد. اگر برنامهای زمانبر اجرا کنیم، میتوانیم با افزودن & آن را در پسزمینه بفرستیم تا پوسته بلافاصله به ما بازگردد.
long_command &
پوسته PID فرایند پسزمینه را گزارش میکند و نشان میدهد که «کار» (job) جدیدی ایجاد شده است.
تعلیق موقت و ادامهٔ اجرا
اگر فرمانی را بدون & آغاز کردهایم، میتوانیم با فشردن ترکیب کلید Ctrl+Z آن را موقتاً متوقف (suspend) کنیم. سپس با bg همان فرمان در پسزمینه ادامه مییابد:
bg %1
در این مثال %1 شمارهٔ کار است. برای بازگرداندن کار به پیشزمینه از fg استفاده میکنیم:
fg %1
زمانی که فقط یک کار متوقف یا در پسزمینه داریم، میتوان شمارهٔ کار را حذف کرد.
مشاهدهٔ فهرست کارها با jobs
jobs
خروجی نمونه:
[1]+ Stopped nano notes.txt
[2]- Running ./backup.sh &
علامت + نشاندهندهٔ کاری است که fg یا bg در صورت عدم تعیین شماره انتخاب خواهند کرد؛ علامت - کار بعدی در اولویت است.
خروج از پوسته هنگام وجود کارها
اگر هنگام خروج (exit یا Ctrl+D) هنوز کارهای فعال داشته باشید، پوسته هشدار میدهد و مانع خروج میشود. برای پایان دادن به همهٔ کارها، آنها را به پیشزمینه برگردانید و با Ctrl+C خاتمه دهید یا از kill استفاده کنید.
سیگنالها و پایان دادن به فرایندها
سیگنالها پیامهایی هستند که هستهٔ سیستمعامل برای اطلاعرسانی یا درخواست اقدام به فرایند ارسال میکند. برخی سیگنالها قابل نادیدهگرفتناند، برخی دیگر (مانند SIGKILL) همیشه باعث پایان فرایند میشوند.
رایجترین سیگنالها:
| سیگنال | نام نمادین | توضیح |
|---|---|---|
| 1 | SIGHUP |
پایان نشست یا «آویزان شدن» پایانه؛ بسیاری از داِمونها پس از دریافت آن تنظیمات را دوباره بارگذاری میکنند. |
| 2 | SIGINT |
اختلال (Interrupt)؛ همان سیگنالی است که با Ctrl+C ارسال میشود و معمولاً باعث خاتمهٔ برنامه میشود. |
| 3 | SIGQUIT |
پایان همراه با core dump؛ معمولاً با Ctrl+\ فرستاده میشود تا برنامه برای عیبیابی ردپا بگذارد. |
| 9 | SIGKILL |
پایان فوری بدون امکان ذخیرهٔ وضعیت؛ فرایند نمیتواند آن را مهار یا نادیده بگیرد. |
| 15 | SIGTERM |
درخواست خاتمهٔ نرم؛ فرایند میتواند قبل از خروج منابع را آزاد کند. |
| 18/19 | SIGCONT |
ادامهٔ اجرای فرایند متوقفشده. |
| 20/17 | SIGSTOP |
توقف اجباری فرایند (مانند Ctrl+Z ولی غیرقابلنادیدهگرفتن). |
توجه: شمارهٔ برخی سیگنالها بسته به معماری کمی تفاوت دارد؛ برای مشاهدهٔ فهرست کامل از
kill -lاستفاده کنید.
استفاده از kill
برای ارسال سیگنال به فرایندی با PID مشخص از kill استفاده میکنیم. اگر سیگنالی تعیین نکنیم، پیشفرض SIGTERM است.
kill 5021 # ارسال SIGTERM
kill -SIGKILL 5021 # پایان اجباری
kill -9 5021 # معادل بالا با شمارهٔ سیگنال
اگر فرایند به شکل متعارف به SIGTERM پاسخ نمیدهد، قبل از متوسل شدن به SIGKILL به آن زمان دهید تا منابع خود را آزاد کند.
killall و pkill
وقتی PID دقیق را نمیدانیم اما نام فرمان مشخص است، killall یا pkill میتوانند کمک کنند:
killall firefox
pkill -u ali ssh
نمونهٔ دوم تمام فرایندهای ssh متعلق به کاربر ali را خاتمه میدهد.
پایان دادن به کارهای پوسته
میتوان شمارهٔ کار را به kill داد تا سیگنال به فرایند پسزمینه ارسال شود:
kill %1
این روش مخصوصاً وقتی چندین نمونه از یک برنامه اجرا شدهاند و تنها میخواهیم یکی از آنها را متوقف کنیم مفید است.
اجرای طولانی و کار در پسزمینهٔ پایدار
گاهی لازم است فرمانی حتی پس از خروج از پوسته ادامه یابد. برای این منظور میتوان از ابزارهایی مانند nohup یا مدیریتکنندههای جلسات (مانند screen و tmux) استفاده کرد.
nohup long_task.sh &
دستور nohup سیگنال SIGHUP را نادیده میگیرد و خروجی را در فایل nohup.out ذخیره میکند تا کار پس از بستن پایانه نیز ادامه یابد.
ابزارهای screen و tmux محیطی مجازی ایجاد میکنند که میتوان آن را جدا (detach) و دوباره متصل کرد، بدون آنکه فرایندهای درونشان متوقف شوند.
تمیز کردن فرایندهای سرکش
در مواقعی که برنامهای دچار «فرار حافظه» یا حلقهٔ بیپایان میشود، میتوانیم با top یا ps فرایند را شناسایی و سپس سیگنال مناسب ارسال کنیم. گامهای پیشنهادی:
- با
topیاps aux --sort=-%cpuفرایند مشکلساز را بیابید. - ابتدا
kill PID(سیگنال پیشفرض) را امتحان کنید. - اگر پاسخ نگرفتید، پس از چند ثانیه دوباره با
kill -SIGTERM PIDتلاش کنید. - در صورت لزوم نهایتاً
kill -SIGKILL PIDرا اجرا کنید.
همواره پس از خاتمه دادن به فرایند، فایلهای موقتی و منابع مشترک را بررسی کنید تا وضعیت ناتمام باقی نماند.
جمعبندی
- فرایند نمونهٔ زندهٔ یک برنامه است که توسط هسته مدیریت میشود.
- پوسته هنگام اجرای فرمانها فرایندهای فرزند ایجاد میکند و کنترل آنها را با مفاهیم پیشزمینه و پسزمینه بر عهده دارد.
- ابزارهایی مانند
ps,topوpstreeدید جامعی از وضعیت فرایندها ارائه میدهند. - با
jobs,bg,fgو میانبرهای صفحهکلید میتوانیم اجرای همزمان چند فرمان را مدیریت کنیم. - سیگنالها زبان مشترک برای خاتمه یا کنترل فرایندها هستند؛
kill,killallوpkillراههای استاندارد ارسال سیگنالاند. - برای اجراهای طولانی و ماندگار، از
nohup,screenیاtmuxبهره ببرید تا فرایندها با قطع نشست از دست نروند.
در فصلهای بعدی با محیط اجرا و متغیرهای پوسته آشنا میشویم تا بتوانیم رفتار فرایندها را دقیقتر شخصیسازی کنیم.