نحوه مدیریت فرایندها با ps و kill و nice در سرور مجازی لینوکس Linux
۱۱ بهمن ۱۴۰۳
مقدمه
یک سرور مجازی لینوکس، مانند هر کامپیوتر مدرن دیگری، برنامههای متعددی را اجرا میکند. این برنامهها، هر کدام فرآیندهای مجزایی شناخته شده و به صورت مجزا، مدیریت میشوند.
در حالی که لینوکس در سطح پایین و پشتصحنه، مدیریت چرخه حیات یک فرآیند (process lifecycle) – مانند راهاندازی (startup)، خاموش شدن (shutdown)، تخصیص حافظه (memory allocation)، و غیره – را بر عهده میگیرد، شما نیاز به یک روش برای تعامل با سیستمعامل دارید تا بتوانید این فرآیندها را در سطح بالاتر، مدیریت کنید.
در این راهنما، با نحوه مدیریت فرآیندها آشنا خواهید شد. لینوکس ابزارهای استاندارد و داخلی متعددی برای این منظور ارائه میدهد. شما این مفاهیم را در محیط Ubuntu 22.0.4 بررسی خواهید کرد، اما هر توزیع مدرن لینوکس به روش مشابهی، عمل میکند.
در ادامه، بخوانید:
- مرحله اول: نحوه مشاهده فرایندهای در حال اجرا در لینوکس
- مرحله دوم: نحوه استفاده از دستور
ps
برای لیستکردن فرایندها - مرحله سوم: نحوه ارسال سیگنالها به فرایندها در لینوکس
- مرحله چهارم: نحوه تنظیم اولویت فرایندها
- نتیجهگیری
مرحله اول – نحوه مشاهده فرایندهای در حال اجرا در لینوکس
میتوانید تمام فرآیندهای در حال اجرا در سرور مجازی خود را با استفاده از دستور top مشاهده کنید:
top
خروجی:
top - 15:14:40 up 46 min, 1 user, load average: 0.00, 0.01, 0.05
Tasks: 56 total, 1 running, 55 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1019600k total, 316576k used, 703024k free, 7652k buffers
Swap: 0k total, 0k used, 0k free, 258976k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 24188 2120 1300 S 0.0 0.2 0:00.56 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.07 ksoftirqd/0
6 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
7 root RT 0 0 0 0 S 0.0 0.0 0:00.03 watchdog/0
8 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 cpuset
9 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 khelper
10 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs
چند خط اول خروجی، آمار کلی سیستم مانند بارگذاری CPU/حافظه و تعداد کل taskهای در حال اجرا را نشان میدهد. در خروجی فوق، میبینید که یک فرایند در حال اجرا وجود دارد و ۵۵ فرایند دیگر به دلیل عدم استفاده فعال از CPU، در حالت خواب (sleeping) هستند.
بخش باقیمانده خروجی، فرایندهای در حال اجرا و آمار مصرف آنها را نشان میدهد. به طور پیشفرض، دستور top
، این فرایندها را بر اساس مصرف CPU، مرتب میکند، بنابراین، شلوغترین فرایندها را در ابتدا، مشاهده میکنید. دستور top
تا زمانی که آن را با Ctrl+C
متوقف نکنید، در شل شما اجرا خواهد شد. اجرای Ctrl+C
، سیگنال پایان (kill signal
) را ارسال میکند و از فرایند میخواهد در صورت امکان، متوقف شود.
نسخه بهبودیافتهای از دستور top
به نام htop
وجود دارد که در اکثر package repositoryها موجود است. در اوبونتو، میتوانید آن را با apt
نصب کنید:
sudu apt update
sudo apt install htop
پس از آن، دستور htop
در دسترس خواهد بود:
htop
خروجی:
Mem[||||||||||| 49/995MB] Load average: 0.00 0.03 0.05
CPU[ 0.0%] Tasks: 21, 3 thr; 1 running
Swp[ 0/0MB] Uptime: 00:58:11
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
1259 root 20 0 25660 1880 1368 R 0.0 0.2 0:00.06 htop
1 root 20 0 24188 2120 1300 S 0.0 0.2 0:00.56 /sbin/init
311 root 20 0 17224 636 440 S 0.0 0.1 0:00.07 upstart-udev-brid
314 root 20 0 21592 1280 760 S 0.0 0.1 0:00.06 /sbin/udevd --dae
389 messagebu 20 0 23808 688 444 S 0.0 0.1 0:00.01 dbus-daemon --sys
407 syslog 20 0 243M 1404 1080 S 0.0 0.1 0:00.02 rsyslogd -c5
408 syslog 20 0 243M 1404 1080 S 0.0 0.1 0:00.00 rsyslogd -c5
409 syslog 20 0 243M 1404 1080 S 0.0 0.1 0:00.00 rsyslogd -c5
406 syslog 20 0 243M 1404 1080 S 0.0 0.1 0:00.04 rsyslogd -c5
553 root 20 0 15180 400 204 S 0.0 0.0 0:00.01 upstart-socket-br
htop
نمایش بهتری از threadهای CPU ارائه میدهد، همچنین، آگاهی آن از پشتیبانی رنگ در ترمینالهای مدرن بیشتر است و گزینههای مرتبسازی بیشتری دارد. برخلاف دستور top
، دستور htop
، همیشه به صورت پیشفرض نصب نیست، اما میتواند به عنوان جایگزینی مناسب در نظر گرفته شود. میتوانید با فشار دادن Ctrl+C
، مانند top
، از htop
خارج شوید. در بخش بعدی، یاد خواهید گرفت چگونه از این ابزارها برای جستجوی فرآیندهای خاص استفاده کنید.
مرحله دوم: نحوه استفاده از دستور ps
برای لیستکردن فرایندها
دستورات top
و htop
یک رابط داشبوردی (dashboard interface) برای مشاهده فرآیندهای در حال اجرا ارائه میدهند که مشابه یک task manager گرافیکی، عمل میکند. یک رابط داشبوردی میتواند یک نمای کلی فراهم کند، اما معمولاً خروجی مستقیمی برای انجام عملیات مختلف، ارائه نمیدهد. برای این منظور، لینوکس دستور استاندارد دیگری به نام ps
ارائه میدهد تا فرآیندهای در حال اجرا را جستجو کند.
اجرای دستور ps
بدون استفاده از آرگومان خاصی، اطلاعات کمی را نمایش میدهد:
ps
خروجی:
PID TTY TIME CMD
1017 pts/0 00:00:00 bash
1262 pts/0 00:00:00 ps
خروجی فوق، تمام فرآیندهای مرتبط با کاربر جاری و session ترمینال فعلی را نشان میدهد. این منطقی است که تنها فرایندهای در حال اجرا، پوسته bash و همان دستور ps باشد. برای به دست آوردن تصویری کاملتر از فرآیندهای سیستم، میتوانید از دستور زیر استفاده کنید:
ps aux
خروجی:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 24188 2120 ? Ss 14:28 0:00 /sbin/init
root 2 0.0 0.0 0 0 ? S 14:28 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 14:28 0:00 [ksoftirqd/0]
root 6 0.0 0.0 0 0 ? S 14:28 0:00 [migration/0]
root 7 0.0 0.0 0 0 ? S 14:28 0:00 [watchdog/0]
root 8 0.0 0.0 0 0 ? S< 14:28 0:00 [cpuset]
root 9 0.0 0.0 0 0 ? S< 14:28 0:00 [khelper]
…
این گزینه به دستور ps میگوید که فرآیندهای متعلق به تمام کاربران را (صرفنظر از ارتباط آنها با ترمینال) به صورت یک قالب خواناتر (human-readable format) نشان دهد.
با استفاده از pipeها (|
) میتوانید در خروجی دستور ps aux
، با استفاده از grep
، به جستجو بپردازید تا نام یک فرآیند خاص را، بیابید. این روش زمانی مفید است که فکر میکنید یک فرآیند دچار مشکل شده یا نیاز به متوقف کردن آن دارید.
ps aux | grep bash
خروجی:
sammy 41664 0.7 0.0 34162880 2528 s000 S 1:35pm 0:00.04 -bash
sammy 41748 0.0 0.0 34122844 828 s000 S+ 1:35pm 0:00.00 grep bash
خروجی فوق، هم فرآیند grep
که به تازگی اجرا کردهاید و هم پوسته bash
که در حال حاضر در حال اجراست را نشان میدهد. همچنین میزان استفاده از حافظه و CPU، مدت زمان اجرای آنها و شناسه فرآیند (Process ID یا PID) آنها را نیز، نمایش میدهد.
یک روش سریع برای به دست آوردن شناسه یک فرآیند (PID)، استفاده از دستور pgrep
است، مثلاً:
pgrep bash
خروجی:
1017
اولین فرآیندی که در هنگام راهاندازی سیستم ایجاد میشود و به نام init
شناخته میشود، شناسه 1
را دریافت میکند:
pgrep init
خروجی:
1
این فرآیند، مسئول ایجاد تمام فرآیندهای دیگر در سیستم است. فرآیندهای بعدی، شماره PID بزرگتری دریافت میکنند. فرآیند والد (parent process) فرآیندی است که مسئول ایجاد یک فرآیند دیگر است. فرآیندهای والد دارای شناسه والد (PPID یا Parent Process ID) هستند که میتوانید آن را در ستونهای خروجی بسیاری از ابزارهای مدیریت فرآیند، از جمله htop
و top
و ps
مشاهده کنید.
هرگونه ارتباط بین کاربر و سیستمعامل در مورد فرآیندها، شامل نام فرآیند و شناسه PID آن است. به همین دلیل، این ابزارها همیشه شامل PID هر فرایند در خروجی خود هستند.
مرحله سوم: نحوه ارسال سیگنالها به فرایندها در لینوکس
در لینوکس، تمام فرآیندها به سیگنالها (signals) پاسخ میدهند. سیگنالها روشی در سطح سیستمعامل برای اطلاعرسانی به برنامهها، جهت خاتمه یا تغییر رفتار آنها هستند. رایجترین روش برای ارسال سیگنال به یک برنامه، استفاده از دستور kill
است. همانطور که از نام آن پیداست، عملکرد پیشفرض این دستور، تلاش برای خاتمه دادن به یک فرآیند، است:
kill PID_of_target_process
این دستور، سیگنال TERM
را به فرآیند ارسال میکند. سیگنال TERM
، از فرآیند به طور مؤدبانه میخواهد که خاتمه یابد. این دستور، این امکان را فراهم میکند که برنامه، عملیات پاکسازی (clean-up) را انجام داده و بهآرامی، بسته شود.
اگر برنامهای رفتار نامناسب داشته باشد و با دریافت سیگنال TERM
خاتمه پیدا نکند، میتوانید سیگنال را با فلگ KILL
قویتر کنید:
kill -KILL PID_of_target_process
این سیگنال به خود برنامه ارسال نمیشود، بلکه مستقیماً به kernel سیستمعامل داده میشود که فرآیند را متوقف کند. این روش برای دور زدن برنامههایی استفاده میشود که به سیگنالهای ارسالشده، بیتوجه هستند.
هر سیگنال دارای شمارهای مرتبط است که میتوانید به جای نام آن، ارسال کنید. به عنوان مثال، میتوانید از -15
به جای -TERM
و از -9
به جای -KILL
، استفاده کنید.
سیگنالها تنها برای خاتمه دادن به برنامهها استفاده نمیشوند. آنها میتوانند برای انجام عملیات دیگری نیز مورد استفاده قرار گیرند. برای مثال، بسیاری از فرآیندهایی که به صورت دائمی در پسزمینه اجرا میشوند (معمولاً daemon نامیده میشوند) به طور خودکار در پاسخ به سیگنال HUP
یا hang-up
، مجدداً راهاندازی میشوند. سرور وب Apache معمولاً اینگونه عمل میکند.
sudo kill -HUP pid_of_apache
دستور بالا باعث میشود که آپاچی، فایل پیکربندی خود را مجدداً بارگذاری کرده و ارائه محتوا را ادامه دهد.
توجه: بسیاری از فرآیندهای پسزمینه، از طریق system services مدیریت میشوند که امکان تعامل بیشتری با هم دارند. در اکثر موارد، ترجیح داده میشود که به جای ارسال سیگنال HUP
، مستقیماً کل سرویس، مجدداً راهاندازی شود.
میتوانید تمام سیگنالهایی که میتوان با kill
ارسال کرد را با استفاده از گزینه -l
لیست کنید:
kill -l
خروجی:
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
به جز استفاده از PIDها، روشهای دیگری نیز برای ارسال سیگنال به فرآیندها وجود دارد. دستور pkill
تقریباً به همان شیوه kill
عمل میکند، اما به جای PID، نام فرآیند را میگیرد:
pkill -9 ping
این دستور معادل زیر است:
kill -9 `pgrep ping`
اگر بخواهید به تمام instanceهای یک فرآیند خاص، سیگنال ارسال کنید، میتوانید از دستور killall
استفاده کنید:
killall firefox
دستور بالا سیگنال TERM
را به تمام instanceهای در حال اجرای firefox
در سیستم ارسال میکند.
مرحله چهارم: نحوه تنظیم اولویت فرایندها
اغلب در سرورهای مجازی، نیاز به تنظیم اولویت فرآیندها خواهید داشت. برخی از فرآیندها ممکن است در ساز و کار سرور شما، خیلی مهم باشد، در حالی که سایر فرآیندها میتوانند در صورت باقیماندن منابع، اجرا شوند. لینوکس اولویتها را از طریق مفهومی به نام niceness
کنترل میکند.
فرآیندهای با اولویت بالا، کمتر nice در نظر گرفته میشوند زیرا، منابع را به خوبی به اشتراک نمیگذارند. در مقابل، فرآیندهای با اولویت پایین، nice هستند؛ چون حداقل منابع موجود را درخواست میکنند. زمانی که دستور top
را اجرا میکنید، ستونی به نام NI
وجود دارد که نشاندهنده مقدار niceness
یک فرایند است:
top
خروجی:
[secondary_label Output]
Tasks: 56 total, 1 running, 55 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.3%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1019600k total, 324496k used, 695104k free, 8512k buffers
Swap: 0k total, 0k used, 0k free, 264812k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1635 root 20 0 17300 1200 920 R 0.3 0.1 0:00.01 top
1 root 20 0 24188 2120 1300 S 0.0 0.2 0:00.56 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.11 ksoftirqd/0
مقدار niceness میتواند بین -19
/-20
(بالاترین اولویت) و 19
/20
(پایینترین اولویت)، بسته به سیستم، متغیر باشد. برای اجرای یک برنامه با مقدار nice خاص، میتوانید از دستور nice
استفاده کنید:
nice -n 15 command_to_execute
دستور فوق، تنها هنگام شروع برنامه جدید، عمل میکند. اگر بخواهید مقدار niceness یک برنامه در حال اجرا را تغییر دهید، از ابزار renice
استفاده کنید:
renice 0 PID_to_prioritize
نتیجهگیری
مدیریت فرآیندها بخش اساسی و مهمی از لینوکس است که تقریباً در هر زمینهای، کاربرد دارد. اطلاع از نوع فرایند، میزان منابع مصرفی آن و مواردی از این قبیل، به شما کمک میکند تا سادهتر از قبل، سرور مجازی خود را، مدیریت و استفاده بهینه کنید.
در صورتی که به یک سرور مجازی دائمی خوب، با قیمت مناسب و پشتیبانی فوقالعاده نیاز دارید، توصیه میشود که از سرور مجازی ایران لیارا، استفاده کنید. از جمله مزیتهای VPS لیارا، سادگی در استفاده، زیر ساخت قوی و منابع کافی آن، است.