لينكس / الأساسي: أسس سطر الأوامر / الدرس 5
تتبع العمليات والمهام والإشارات
افهم دورة حياة العملية وافحص عمليات محددة وميّز الإنهاء المنظم من الإنهاء القسري.
في هذه الصفحة
أهداف الدرس
- ربط العمليات الأم ومعرفات العمليات وحالة الخروج.
- التمييز بين مهمة الصدفة وعملية نظام التشغيل.
- اختيار الإشارات وفق السلوك الموثق.
للعمليات هويات وأعمار
العملية برنامج جارٍ له هوية اعتماد وواصفات مفتوحة وخرائط ذاكرة ومجلد عمل. يعرّفها رقم العملية طوال عمرها فقط وقد تعيد النواة استخدامه لاحقاً. تبدأ العملية الأم أبناءً وتجمع حالة اكتمالهم عبر wait. ويمكن للبرنامج استبدال صورته التنفيذية باستخدام exec دون تغيير معرفه. تشترك الخيوط في كثير من الحالة مع تنفيذ مستقل. تشرح هذه الفروق كيف ينشئ أمر واحد عمليات متعددة ولماذا لا يكفي الاسم وحده لتحديد هدف.
فحص عمليات محددة
يعرض ps لقطة لحظية لا حقيقة مستمرة. اختر أعمدة صريحة للمعرف والأب والحالة والأمر، وافحص المالك قبل التصرف. النوم عادة انتظار طبيعي وليس دليلاً على التعليق. خرجت العملية الزومبي لكن الأب لم يجمع حالتها بعد، لذلك لا يفيد تكرار إرسال إشارات قتل لها. يعرض /proc معلومات حالية عندما تسمح الصلاحيات. وقد تحوي الوسائط والبيئات أسراراً؛ فلا تنشر قوائم غير مرشحة ولا تجمع تفاصيل مستخدم آخر بلا حاجة.
sleep 1 &
child=$!
ps -p "$child" -o pid=,ppid=,stat=,comm=
wait "$child"
printf 'completed=%s\n' "$?"
تختلف المعرفات. يفحص المثال عملية sleep الجديدة التي أنشأها فقط وينتظرها؛ فيطبع الاكتمال الطبيعي completed=0.
التحكم في المهام من مسؤولية الصدفة التفاعلية
تقابل مهمة Bash التفاعلية عادة سلسلة أنابيب ومجموعة عملياتها. يبدأ & العمل بصورة غير متزامنة، ويحفظ $! معرف أحدث عملية خلفية. يعرض jobs مهام الصدفة الحالية لا جميع عمليات النظام. يطلب Ctrl-Z عادة التعليق عبر الطرفية، ويستأنف bg المهمة في الخلفية، ويعيد fg الطرفية لها. المهمة الموقوفة لم تكتمل. ينبغي للبرامج النصية غير التفاعلية إدارة معرفات الأبناء والانتظار صراحة، لا افتراض توفر ترقيم المهام التفاعلي.
تطلب الإشارات أفعالاً محددة
يرسل kill إشارة، ولا يعني اسمه أن كل استدعاء يدمر العملية فوراً. تطلب SIGTERM الإنهاء وتتيح التنظيف إذا ثبت البرنامج معالجاً لها. تأتي SIGINT عادة من Ctrl-C إلى مجموعة المقدمة. تنهي SIGKILL دون إتاحة معالج، ولا يمكن معالجة SIGSTOP أيضاً. فضّل الأسماء الرمزية لأن بعض الأرقام تختلف حسب المعمارية. أكد المالك والهوية الحالية والنطاق قبل الإرسال. قد يصيب التطابق العام بالاسم عمليات أخرى أو معرفاً أُعيد استخدامه.
bash -c 'trap "echo term-observed; exit 0" TERM; kill -s TERM "$$"'
term-observed
يثبت Bash الداخلي معالجاً ويرسل TERM إلى نفسه. لا يُستهدف معرف غير متعلق. يطبع المعالج رسالة ويخرج بنجاح.
يحتاج عمل الخلفية إلى سياسة عمر
لا يحوّل & بعد الأمر العمل إلى خدمة موثوقة. فقد تنهيه إغلاق الطرفية أو سياسات الجلسة أو الواصفات الموروثة أو الإشارات غير المعالجة. يغيّر nohup التعامل مع إنهاء الاتصال لكنه لا يوفر ترتيب البدء أو فحص الصحة أو الإشراف على إعادة التشغيل. يناسب مدير خدمات أو مجدول الأعمال المتكررة والطويلة. وفي برنامج صغير سجل كل ابن وانتظر اكتماله وانقل الفشل. وعند الإلغاء أتح مهلة محدودة للتنظيف ووثق البيانات المؤقتة التي قد تبقى.
الأخطاء الشائعة وإصلاحها
إرسال إشارة إلى معرف مُخمّن
- لماذا يحدث؟
- قد تحدد قائمة قديمة أو رقم منسوخ عمراً مختلفاً.
- كيف تصلحه؟
- أعد فحص العملية المحددة ومالكها قبل التصرف.
- كيف تتجنب تكراره؟
- التقط الأبناء مباشرة عبر $! وحدد نطاقهم.
استخدام SIGKILL أولاً
- لماذا يحدث؟
- اختلط الإنهاء القسري بالإغلاق المعتاد.
- كيف تصلحه؟
- فضّل وسيلة إغلاق منظمة موثقة وانتظاراً محدوداً.
- كيف تتجنب تكراره؟
- تعلم متطلبات التنظيف والإغلاق قبل الإلغاء.
اعتبار المهمة الموقوفة مكتملة
- لماذا يحدث؟
- علّق Ctrl-Z التنفيذ ولم ينهه.
- كيف تصلحه؟
- افحص jobs واستأنف مهمة المختبر أو أنهها بقرار مقصود.
- كيف تتجنب تكراره؟
- ميّز حالات الوقوف والعمل والخروج.
اختبر فهمك
1. لماذا قد تبقى عملية زومبي بعد SIGKILL؟
اعرض الحل المشروح
انتهى عملها التنفيذي بالفعل، ولم يبق إلا سجل صغير يحتاجه انتظار الأب. الحل تشخيص سبب عدم جمع الأب لحالات أبنائه؛ فلا يجعل إرسال الإشارات المتكرر الابن المنتهي ينظف أو يجمع نفسه.
2. يبدأ برنامج نصي ابنين ثم يخرج فوراً. صف عقد اكتمال أكثر موثوقية.
اعرض الحل المشروح
احفظ معرف كل ابن فوراً، وانتظر كلاً منهما، وسجل النتيجتين، وأعد فشلاً موثقاً إذا أخفقت مهمة مطلوبة. حدد كيف يصل الإلغاء للابنين وما يلزم من تنظيف. لا يشهد البدء في الخلفية وحده على الاكتمال.
أهم ما تعلمته
- افحص هوية العملية ونطاقها قبل إرسال إشارة.
- استخدم wait لتحويل اكتمال الابن إلى نتيجة.