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

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

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

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

أجزاء أخرى:

يمكنك أيضًا التحقق من قناتي على برقية =)

إنذار! هناك معمل لهذه المحاضرة! ينظر جيثب

API العملية

دعونا نلقي نظرة على مثال لإنشاء عملية في نظام UNIX. يحدث ذلك من خلال مكالمتين للنظام فرع() и إكسيك ().

شوكة الاتصال ()

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

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

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

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

إنتظار مكالمة()

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

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

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

استدعاء exec()

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

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

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

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

يسمح تقسيم fork() & exec() لـ Shell بالقيام بالأشياء التالية، على سبيل المثال:
ملف مرحاض > new_file.

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

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

المصدر: www.habr.com

إضافة تعليق