دليل

العمليات في Linux: ps وtop وhtop وkill والإشارات وnice

آخر تحديث: · Skillaria.Top

تُعرض عمليات Linux بالأمر ps aux (لقطة واحدة)، وبالأمرين top وhtop (قائمة متجددة مع الحمل). وتُنهى العملية بالأمر kill PID الذي يرسل افتراضياً إشارة SIGTERM المهذبة، ولا يُلجأ إلى kill -9 (SIGKILL) إلا إذا لم تستجب العملية. وتُضبط الأولوية بـ nice عند التشغيل وبـ renice لعملية تعمل، ضمن المدى من -20 إلى 19.

كل برنامج يعمل في Linux عملية لها رقم PID خاص بها ومالك وحالة وأولوية. يمكن عرض العمليات بالأوامر ps وtop وhtop، وإنهاؤها بالأمر kill، وتغيير أولويتها بـnice وrenice. وفيما يلي نشرح كيفية قراءة مخرجات هذه الأوامر، وأي إشارة ترسل ومتى، ولماذا لا ينبغي أن يكون kill -9 أول ما يخطر ببالك.

ما هي العملية وما هو PID

العملية هي برنامج أثناء تنفيذه: الشيفرة والذاكرة والملفات المفتوحة ومجموعة من الخصائص. يمنح النواة لكل عملية معرّفاً فريداً هو PID، ويحفظ كذلك PPID وهو رقم الأب الذي أطلقها. وأول عملية في النظام برقم PID 1 هي عادةً systemd، وهي «الجد» لكل العمليات الأخرى.

تظهر العملية الجديدة في خطوتين. أولاً يستدعي الأب fork() فيحصل على نسخة منه، ثم تستدعي النسخة execve() فتستبدل شيفرتها بشيفرة البرنامج الجديد. وعندما تكتب ls في الطرفية، ينفذ bash هذا بالضبط، وينتظر انتهاء الابن عبر wait().

$ echo $$          # PID الصدفة الحالية
4182
$ ps -o pid,ppid,cmd -p $$
    PID    PPID CMD
   4182    4170 -bash

عرض العمليات بالأمر ps

يلتقط ps لقطة واحدة: يعرض العمليات في لحظة التشغيل ثم ينتهي. ومن دون معاملات يعرض عمليات الطرفية الحالية فقط، لذلك يُستخدم عملياً أحد الخيارين التاليين في الغالب.

$ ps aux | head -5
USER       PID %CPU %MEM    VSZ   RSS TTY   STAT START   TIME COMMAND
root         1  0.0  0.3 168540 12780 ?     Ss   09:12   0:03 /sbin/init
root         2  0.0  0.0      0     0 ?     S    09:12   0:00 [kthreadd]
www-data  1532  1.2  2.1 412308 86420 ?     S    09:15   1:47 php-fpm: pool www
postgres  1610  0.4  3.8 221004 154312 ?    Ss   09:15   0:31 postgres: checkpointer

هنا a تعني عمليات كل المستخدمين، وu تعني التنسيق المفصّل مع المالك، وx تعني تضمين العمليات التي لا طرفية لها (الخدمات الخلفية). وصيغة System V البديلة هي ps -ef، وتعرض PPID، وهذا مفيد لمعرفة من أطلق من.

العمودالمعنى
PIDمعرّف العملية
%CPU، %MEMحصة المعالج والذاكرة الفعلية
VSZالذاكرة الافتراضية بالكيلوبايت (بما فيها غير المحمّل في RAM)
RSSالذاكرة الفعلية المشغولة بالكيلوبايت
STATحالة العملية (R وS وD وZ وT) والأعلام
TIMEوقت المعالج المتراكم، لا مدة التشغيل

حيل مفيدة مع ps

# أعلى 10 عمليات من حيث الذاكرة
ps aux --sort=-%mem | head -11

# أعلى 10 عمليات من حيث المعالج
ps aux --sort=-%cpu | head -11

# أعمدة مخصصة
ps -eo pid,ppid,user,ni,stat,etime,cmd

# شجرة العمليات
ps -ef --forest
pstree -p

# البحث عن PID بالاسم
pgrep -a nginx
pidof nginx

خطأ كلاسيكي هو البحث بـps aux | grep nginx فيظهر في النتيجة الأمر grep نفسه. استخدم pgrep أو الحيلة grep [n]ginx، التي لا تطابق سطر الأمر الخاص بها.

حالات العمليات: R وS وD وZ وT

الحرف في العمود STAT ليس زائداً، بل هو الحالة الفعلية للعملية. ومنها يُفهم الحمل، وهل سينفع kill أصلاً.

الرمزالحالةالمعنى العملي
RRunningتعمل أو تنتظر دورها في المعالج
SInterruptible sleepتنتظر حدثاً (شبكة، إدخال، مؤقت)؛ الحالة الطبيعية لمعظم العمليات
DUninterruptible sleepتنتظر إدخال/إخراج داخل النواة، ولا تُسلَّم لها الإشارات
ZZombieانتهت، لكن أباها لم يأخذ رمز خروجها
TStoppedأوقفتها إشارة SIGSTOP أو Ctrl+Z

الرموز الإضافية بعد الحرف مفيدة أيضاً: s قائد الجلسة، و+ عملية المقدمة في الطرفية، و< أولوية أعلى، وN أولوية أدنى، وl متعددة الخيوط.

عملية في الحالة D

العملية في D موجودة داخل استدعاء نظامي وتنتظر مثلاً ردّ القرص أو شبكة NFS معلّقة. لا تصلها أي إشارة، حتى SIGKILL. لذلك يكون kill -9 عديم الفائدة هنا: ابحث عن سبب الانتظار بالنظر في iostat وdmesg وحالة التخزين الشبكي.

العمليات الزومبي

الزومبي ميتة بالفعل: لا تستهلك معالجاً ولا ذاكرة، بل تشغل سطراً فقط في جدول العمليات. ولا يمكن قتلها لأنها منتهية أصلاً. وتختفي عندما يستدعي أبوها wait()، أو عندما ينتهي الأب نفسه فيتبناها PID 1.

# البحث عن الزومبي وآبائها
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/'

الزومبي الواحد لا ضرر منه. أما إذا كانت بالمئات وتزداد، فالخطأ في البرنامج الأب، ويجب إصلاحه أو إعادة تشغيله.

top: العمليات والحمل في الوقت الفعلي

يعرض top القائمة نفسها، لكنه يحدّثها كل بضع ثوانٍ ويعرض ملخصاً للنظام. وهو أول أمر يُشغَّل عندما «يتباطأ الخادم».

top - 14:21:07 up 12 days,  3:02,  2 users,  load average: 1.84, 1.20, 0.95
Tasks: 213 total,   2 running, 211 sleeping,   0 stopped,   0 zombie
%Cpu(s): 23.1 us,  4.2 sy,  0.0 ni, 70.3 id,  1.9 wa,  0.0 hi,  0.5 si,  0.0 st
MiB Mem :   7821.4 total,    412.6 free,   3105.8 used,   4303.0 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.   4398.2 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   1532 www-data  20   0  412308  86420  14212 R  38.2   1.1   1:47.31 php-fpm
   1610 postgres  20   0  221004 154312 148900 S   6.0   1.9   0:31.08 postgres

أهم ما في السطر %Cpu(s): us كود المستخدم، وsy النواة، وid الخمول، وwa انتظار القرص. وارتفاع wa مع معالج فارغ علامة واضحة على أن عنق الزجاجة في الإدخال والإخراج.

مفاتيح top السريعة

المفتاحالإجراء
P / Mترتيب حسب المعالج / حسب الذاكرة
1عرض كل نواة على حدة
cسطر الأمر الكامل
uتصفية حسب المستخدم
kإرسال إشارة إلى عملية
rتغيير nice للعملية
Hعرض الخيوط
qخروج

للسكريبتات والسجلات يفيد الوضع الدفعي: يعرض top -b -n 1 | head -20 لقطة واحدة دون تفاعل. ولمتابعة عملية بعينها استخدم top -p 1532.

Load Average هو طابور وليس نسبة مئوية

الأرقام الثلاثة في load average هي متوسط طول الطابور خلال 1 و5 و15 دقيقة. وتدخل في Linux إلى هذا الطابور العمليات في الحالتين R وD، أما النوم العادي S فلا. ويُقارن الحمل بعدد الأنوية (nproc): على 4 أنوية تعني القيمة 4 تحميلاً كاملاً، والقيمة 12 تعني طابوراً ثلاثة أضعاف الإمكانات.

إذا كان الحمل مرتفعاً والمعالج خامل، فابحث عن العمليات في D: ps -eo stat,pid,cmd | grep '^D'. وغالباً ما يكون السبب قرصاً بطيئاً أو تخزيناً شبكياً.

htop: بديل مريح لـ top

يعرض htop المعلومات نفسها، لكن بمؤشرات ملونة لكل نواة، مع التمرير ودعم الفأرة وشجرة العمليات. وعادةً يلزم تثبيته: sudo apt install htop أو sudo dnf install htop.

  • F3 أو / — البحث عن عملية بالاسم؛
  • F4 — مرشّح يُبقي المطابقات فقط؛
  • F5 أو t — شجرة «الأب — الأبناء»؛
  • F6 — اختيار عمود الترتيب؛
  • F7 / F8 — خفض nice أو رفعه؛
  • F9 — قائمة الإشارات للعملية المختارة؛
  • Space — تحديد عدة عمليات لإجراء جماعي.

على الخوادم التي لا يمكن فيها تثبيت شيء، يكفي top، فكل العمليات الأساسية موجودة فيه أيضاً.

إنهاء العملية: kill والإشارات

لا يقوم الأمر kill بـ«القتل» في الحقيقة، بل يرسل إشارة إلى العملية. وما يحدث بعد ذلك يعتمد على الإشارة وعلى طريقة معالجة البرنامج لها.

الإشارةالرقمالغرض
SIGHUP1انقطاع الطرفية؛ كثير من الخدمات تعيد قراءة الإعداد عندها
SIGINT2المقاطعة، أي ما يفعله Ctrl+C
SIGKILL9إنهاء قسري من النواة، ولا يمكن اعتراضه
SIGTERM15طلب بالإنهاء بهدوء؛ وهي الافتراضية في kill
SIGSTOP19إيقاف مؤقت، ولا يمكن اعتراضه
SIGCONT18متابعة عملية متوقفة
SIGTSTP20إيقاف من الطرفية، أي Ctrl+Z

الأرقام موضحة لمعماريتي x86 وARM؛ والقائمة الكاملة تعرضها kill -l. وكتابة اسم الإشارة أدق من كتابة رقمها.

kill 1532              # SIGTERM
kill -TERM 1532        # الشيء نفسه صراحةً
kill -HUP $(pidof nginx)   # إعادة قراءة الإعداد
kill -STOP 1532; kill -CONT 1532
kill -0 1532 && echo "العملية حية"

الإشارة 0 لا ترسل شيئاً، بل تتحقق فقط من وجود العملية ومن صلاحيتك لمراسلتها، وهذا مفيد في السكريبتات.

لماذا لا تبدأ بـ kill -9

تعطي SIGTERM البرنامجَ فرصة لإغلاق الملفات وتفريغ المخازن وحذف ملفات القفل وإنهاء المعاملات بشكل صحيح. أما SIGKILL فيقطع كل شيء فوراً: تضيع البيانات غير المكتملة وتبقى الملفات المؤقتة، وقد تدخل قاعدة البيانات عند التشغيل التالي في مرحلة الاستعادة.

التسلسل الصحيح هو:

  1. أرسل kill PID (SIGTERM).
  2. انتظر من 5 إلى 30 ثانية مع التحقق بـkill -0 PID.
  3. فقط إذا بقيت العملية حية ولم تكن في الحالة D — أرسل kill -9 PID.

وللخدمات التي تعمل تحت systemd لا تتعامل مع PID يدوياً: إذ يرسل systemctl stop الإشارة SIGTERM، ثم ينتظر المهلة، ثم يُكمل بـSIGKILL.

pkill وkillall: بالاسم

pkill -f "python worker.py"   # بسطر الأمر الكامل
pkill -u alice                 # كل عمليات المستخدم
killall -TERM node             # كل العمليات باسم node
pgrep -l -f worker             # تحقّق أولاً مما سيقع تحت النمط

قبل أي pkill جماعي شغّل pgrep بالنمط نفسه: إذ يطابق الخيار -f أي جزء من سطر الأمر، ويسهل أن يصيب ما ليس مقصوداً.

يمكن إرسال الإشارات إلى عملياتك فقط، أما عمليات غيرك فتحتاج إلى sudo. ورسالة Operation not permitted تعني ذلك تحديداً.

أولوية العمليات: nice وrenice

قيمة nice تُخبر المجدول بمن يتنازل عن المعالج. والمدى من -20 (أعلى أولوية) إلى 19 (يتنازل للجميع)، والافتراضي 0. تظهر القيمة في top في العمود NI، أما PR فهو أولوية داخلية مشتقة.

# تشغيل مهمة ثقيلة بأولوية منخفضة
nice -n 10 tar czf backup.tar.gz /var/www

# خفض أولوية عملية قائمة
renice -n 15 -p 1532

# رفع الأولوية (لـroot فقط)
sudo renice -n -5 -p 1610

# كل عمليات المستخدم
sudo renice -n 10 -u alice

يستطيع المستخدم العادي خفض أولوية عملياته فقط، والقيم السالبة متاحة لـroot وحده. وتجدر الإشارة إلى حدّ nice: إنه يؤثر في المعالج فقط. إذا كانت المهمة تبطئ النظام عبر القرص، فاستخدم ionice -c3 الأمر، وهي فئة الخمول التي تحصل على القرص فقط حين لا يحتاجه أحد.

العمليات الخلفية ومهام الصدفة

يمكن تشغيل أمر في الخلفية بإضافة &، أو إيقافه مؤقتاً بـCtrl+Z. وتحتفظ الصدفة بقائمة من المهام تُدار بأوامر مدمجة.

$ long_task &
[1] 5120
$ jobs
[1]+  Running    long_task &
$ fg %1        # إعادتها إلى المقدمة
^Z             # إيقاف مؤقت (SIGTSTP)
$ bg %1        # متابعتها في الخلفية

عند إغلاق الطرفية ترسل الصدفة SIGHUP إلى المهام فتنتهي. ولكي تبقى العملية بعد الخروج شغّلها عبر nohup الأمر &، أو افصلها بالأمر disown، أو استخدم tmux. وللعمل الدائم الأفضل تحويلها إلى خدمة systemd.

سيناريوهات تشخيص شائعة

من يستهلك المعالج

top -o %CPU            # أو P داخل top
ps -eo pid,user,%cpu,etime,cmd --sort=-%cpu | head

إذا كانت عملية تستهلك المعالج دون فائدة، فاخفض أولويتها أولاً بـrenice، فهذا آمن ويمنحك وقتاً لفهم الأمر.

من يشغل المنفذ

sudo ss -ltnp | grep :8080
sudo lsof -i :8080

ستظهر في المخرجات رقم PID، ومنه يمكن الوصول عبر /proc/PID/ إلى الملف التنفيذي (exe) ومجلد العمل (cwd) والمعاملات (cmdline).

عملية اختفت فجأة

السبب الشائع هو OOM Killer الذي يقتل العمليات عند نفاد الذاكرة. للتحقق: dmesg -T | grep -i oom أو journalctl -k | grep -i "killed process".

الخلاصة

لإدارة العمليات في Linux تكفي مجموعة صغيرة من الأوامر: ps aux للقطة، وtop وhtop للمراقبة، وkill مع الإشارة الصحيحة للإنهاء، وnice/renice للأولويات. اقرأ حالة العملية قبل أن تتصرف: فالزومبي والعمليات في D لا تُعالَج بالإشارات. وابدأ دائماً بـSIGTERM، واترك kill -9 للحالات القصوى. وقد جرى شرح العمليات والذاكرة وLoad Average واستدعاءات النظام بعمق في درس Linux.

الأسئلة الشائعة

ما الفرق بين ps aux وps -ef؟

هما صيغتان لأمر واحد: aux بنمط BSD مع أعمدة %CPU وMEM وSTAT، والخيار -ef بنمط System V مع عمود PPID. وعدد العمليات المعروضة في الحالتين واحد، وهو كل عمليات النظام.

كيف أعرف عدد العمليات الجارية في النظام؟

أسهل طريقة هي النظر إلى سطر Tasks في top، أو تنفيذ ps -e --no-headers | wc -l. ولعدد الخيوط استخدم ps -eLf --no-headers | wc -l.

لماذا لا تنتهي العملية حتى بعد kill -9؟

إما أنها في الحالة D وتنتظر إدخال/إخراج داخل النواة، وإما أنها زومبي منتهية أصلاً. في الحالة الأولى ابحث عن مشكلة في القرص أو التخزين الشبكي، وفي الثانية أصلح الأب أو أعد تشغيله.

ماذا يحدث إذا أنهيت العملية ذات PID 1؟

تحمي النواة init: لا تُسلَّم له الإشارات العادية، بما فيها SIGKILL من المستخدم، ما لم يكن قد عالجها. وإذا انتهى init فعلاً يتعطل النظام بـkernel panic.

كيف أحدّ من استخدام الذاكرة لعملية؟

لخدمة systemd حدّد MemoryMax= في ملف الوحدة، ولتشغيل لمرة واحدة استخدم systemd-run --scope -p MemoryMax=500M الأمر. وهذا يعمل عبر cgroups وهو أدق من ulimit -v القديم.

تعلّم هذا الموضوع بالفيديو

يُشرح هذا الموضوع بالتفصيل مع التطبيق العملي في دورة «Linux: с нуля до уверенного администрирования».

الانتقال إلى الدورة