أنظمة التشغيل: ثلاث قطع سهلة. الجزء 3: API العملية (الترجمة)

مقدمة في أنظمة التشغيل


مرحبا يا هبر! أود أن ألفت انتباهكم إلى سلسلة من المقالات المترجمة لأدب واحد مثير للاهتمام في رأيي - OSTEP. تناقش هذه المقالة بعمق أعمال أنظمة التشغيل المشابهة لنظام التشغيل يونكس ، أي العمل مع العمليات ، وجداول المواعيد المختلفة ، والذاكرة ، والمكونات المماثلة الأخرى التي تشكل نظام التشغيل الحديث. الأصلي لجميع المواد التي يمكنك أن ترى هنا . يرجى ملاحظة أن الترجمة تمت بدون احتراف (بحرية تامة) ، لكن آمل أن أحتفظ بالمعنى العام.

يمكن العثور على العمل المختبري حول هذا الموضوع هنا:


أجزاء أخرى:


ويمكنك إلقاء نظرة على قناتي في برقية =)

Alyarm! يوجد مختبر لهذه المحاضرة! مشاهدة جيثب

API عملية



النظر في مثال على إنشاء عملية على نظام UNIX. يحدث من خلال جهازي نظام المكالمات fork () و exec () .

استدعاء شوكة ()


صورة

خذ بعين الاعتبار برنامج يقوم بإجراء مكالمة fork (). ستكون نتيجة تنفيذه على النحو التالي.

صورة

بادئ ذي بدء ، ندخل الوظيفة الرئيسية () وننفذ مخرجات السلسلة على الشاشة. تحتوي السلسلة على معرف العملية ، والذي يسمى في الأصل معرف العملية أو معرف العملية. يتم استخدام هذا المعرف على UNIX للإشارة إلى العملية. سيطلب الأمر التالي شوكة (). في هذه المرحلة ، يتم إنشاء نسخة دقيقة تقريبًا من العملية. بالنسبة لنظام التشغيل ، يبدو كما لو كان النظام يعمل كما لو أن نسختين من البرنامج نفسه ، والتي بدورها ستنهي وظيفة fork (). لن يتم تنفيذ العملية التابعة التي تم إنشاؤها حديثًا (نسبة إلى العملية الأصل التي أنشأتها) ، بدءًا من الوظيفة الرئيسية (). يجب أن نتذكر أن العملية الفرعية ليست نسخة دقيقة من العملية الأصل ، على وجه الخصوص ، لها مساحة عنوان خاصة بها ، وسجلاتها الخاصة ، ومؤشرها الخاص للتعليمات القابلة للتنفيذ ، وما شابه. وبالتالي ، ستكون القيمة التي يتم إرجاعها إلى الطالب للدالة fork () مختلفة. على وجه الخصوص ، ستحصل العملية الأصل على قيمة PID لعملية الطفل كإرجاع ، وسيحصل الطفل على قيمة تساوي 0. استنادًا إلى رموز الإرجاع هذه ، من الممكن بالفعل فصل العمليات وإجبار كل منهما على القيام بعمله. علاوة على ذلك ، فإن تنفيذ هذا البرنامج غير محدد بدقة. بعد الانقسام إلى عمليتين ، يبدأ نظام التشغيل في متابعتهما أيضًا ، والتخطيط لعملهما. إذا تم تنفيذه على معالج أحادي النواة ، فستستمر إحدى العمليات في العمل ، وفي هذه الحالة ، فإن الوالد ، وبعد ذلك ستتلقى العملية التابعة السيطرة. عند إعادة التشغيل ، قد يكون الموقف مختلفًا.

نداء الانتظار ()


صورة

النظر في البرنامج التالي. في هذا البرنامج ، نظرًا لوجود مكالمة wait () ، ستنتظر العملية الأصل دائمًا إكمال العملية الفرعية لعملها. في هذه الحالة ، نحصل على إخراج نص محدد بدقة على الشاشة.

صورة

استدعاء exec ()


صورة

النظر في الدعوة إلى exec () . مكالمة النظام هذه مفيدة عندما نريد تشغيل برنامج مختلف تمامًا. هنا سوف ندعو execvp () لتشغيل برنامج wc ، وهو برنامج عد الكلمات. ماذا يحدث عندما يتم استدعاء exec ()؟ يتم تمرير اسم الملف القابل للتنفيذ وبعض المعلمات إلى هذه المكالمة كوسائط. بعد ذلك ، يتم تنزيل التعليمات البرمجية والبيانات الثابتة من هذا الملف القابل للتنفيذ ويتم الكتابة فوق القطاع الخاص به مع التعليمات البرمجية. يتم إعادة تهيئة المقاطع المتبقية من الذاكرة ، مثل المكدس و الكومة. بعد ذلك يقوم نظام التشغيل ببساطة بتنفيذ البرنامج ، ويمرره مجموعة من الوسائط. وبالتالي ، لم نقم بإنشاء عملية جديدة ، لقد قمنا ببساطة بتحويل برنامج التشغيل الحالي إلى برنامج آخر قيد التشغيل. بعد تنفيذ exec () ، يعطي السليل انطباعًا بأن البرنامج الأصلي لم يبدأ من حيث المبدأ.

يعد تعقيد التشغيل هذا أمرًا طبيعيًا تمامًا لقذيفة Unix ، ويسمح لهذه shell بتنفيذ التعليمات البرمجية بعد استدعاء fork () ، ولكن قبل استدعاء exec () . مثال على هذا الكود يمكن أن يعدل بيئة الصدفة حسب احتياجات البرنامج الذي يتم إطلاقه ، قبل إطلاقه مباشرة.

شل هو مجرد برنامج مستخدم. إنها تظهر لك الخط السريع وتنتظر منك كتابة شيء ما عليه. في معظم الحالات ، إذا قمت بكتابة اسم البرنامج هناك ، فستجد shell موقعها ، وتستدعي طريقة fork () ، ثم لإنشاء عملية جديدة ، ستستدعي بعض أنواع exec () وتنتظر تنفيذها ليتم تنفيذها باستخدام استدعاء wait (). عند اكتمال العملية الفرعية ، تعود shell من المكالمة wait () وتعرض المطالبة مرة أخرى وتنتظر إدخال الأمر التالي.

يتيح فصل الشوكة () & exec () للقشرة القيام بالأمور التالية ، على سبيل المثال:
wc file> new_file.

في هذا المثال ، تتم إعادة توجيه الإخراج من wc إلى ملف. إن الطريقة التي يحقق بها shell هذا الأمر بسيطة للغاية - عند إنشاء عملية تابعة قبل استدعاء exec () ، تغلق shell دفق الإخراج القياسي وتفتح ملف new_file ، لذلك سيتم إعادة توجيه جميع المخرجات من برنامج wc الذي تم تشغيله إلى الملف بدلاً من الشاشة.

يتم تنفيذ أنابيب UNIX بطريقة مماثلة ، مع اختلاف أنها تستخدم استدعاء توجيه الإخراج (). في هذه الحالة ، سيتم توصيل دفق الإخراج للعملية بقائمة انتظار الأنابيب الموجودة في النواة التي سيتم إرفاق دفق دخل عملية أخرى بها.

Source: https://habr.com/ru/post/ar447182/


All Articles