البرمجة

تسلسل العمليات واستدعاءي Fork و Exec

تسلسل العمليات الهرمي واستدعاءات النظام Fork و Exec في نظام تشغيل الحاسوب

تُعد العمليات في نظام تشغيل الحاسوب من المفاهيم الأساسية التي تساهم في تنظيم وتشغيل البرامج بشكل متزامن وفعّال. ومن بين الخصائص الجوهرية التي تميز نظم التشغيل الحديثة هي قدرتها على إنشاء عملية جديدة من عملية موجودة، وهو ما يُعرف بإنشاء العمليات الفرعية أو العمليات الوليدة (Child Processes)، مما يشكل بنية هرمية بين العمليات. لتحقيق ذلك، توفر أنظمة التشغيل مجموعة من استدعاءات النظام، أشهرها Fork و Exec، اللتان تلعبان دورًا رئيسيًا في إدارة العمليات، وخصوصًا في نظم تشغيل يونكس ولينكس.

في هذا المقال الموسع، سيتم تناول مفهوم تسلسل العمليات الهرمي، والوظائف التي تؤديها استدعاءات النظام Fork و Exec، وكيفية تفاعلها لتحقيق إنشاء وإدارة العمليات في بيئة نظام التشغيل، بالإضافة إلى تفصيل كيفية عملها، تأثيرها على الذاكرة، والتحكم في العمليات، مع عرض جدول توضيحي يسهل فهم الفرق بينهما.


مفهوم تسلسل العمليات الهرمي في نظم التشغيل

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

لماذا نحتاج إلى تسلسل هرمي للعمليات؟

  1. تنظيم العمليات: يساعد التنظيم الهرمي في معرفة علاقات العمليات بعضها ببعض، ما يسهل إدارة العمليات وتتبعها.

  2. التحكم والصلاحيات: العمليات الوليدة ترث بعض خصائص العمليات الأصلية، مما يضمن بقاء البيئة التنفيذية منظمة.

  3. إدارة الموارد: عمليات الأب تُمكنها التحكم في عملياتها الوليدة، مثل إيقافها، استئنافها، أو إنهائها، ما يساعد في التحكم الفعلي في استخدام الموارد.

  4. تسهيل الاتصال بين العمليات: حيث يمكن للعمليات المرتبطة في نفس الشجرة تبادل البيانات ومزامنة التنفيذ بشكل أفضل.

في أنظمة مثل Unix وLinux، تنشأ جميع العمليات من العملية الأصلية المعروفة بـ init (في الإصدارات القديمة) أو systemd (في الإصدارات الحديثة)، وهذه تعتبر الجذر في شجرة العمليات.


استدعاء النظام Fork

يُعد Fork من أهم استدعاءات النظام في بيئة Unix-like لإنشاء عملية جديدة. عند تنفيذ هذا الاستدعاء، يقوم النظام بإنشاء نسخة طبق الأصل من العملية التي طلبت الاستدعاء، بحيث تكون العملية الجديدة هي العملية الوليدة.

كيفية عمل Fork

  • عندما تستدعي عملية الأمر fork، يتم نسخ العملية الحالية (العملية الأصلية أو الأب) لتكوين عملية جديدة (العملية الوليدة).

  • العملية الوليدة تحصل على نسخة متطابقة من الذاكرة، سجلات المعالج، مؤشرات الملفات المفتوحة، ومجمل حالة العملية الأب.

  • بعد الانتهاء من الاستدعاء، يتم تنفيذ كل من العملية الأب والعملية الوليدة بشكل منفصل ومستقل.

  • الفرق الأساسي في التنفيذ بين العمليتين يكون من خلال قيمة المرجع التي يُرجعها استدعاء fork:

    • في العملية الأب، يقوم fork بإرجاع معرّف العملية الوليدة (PID).

    • في العملية الوليدة، يقوم fork بإرجاع القيمة 0.

نقاط هامة في Fork

  • نسخ الذاكرة: نظام التشغيل قد لا ينسخ الذاكرة فعليًا إلا عند محاولة إحدى العمليتين تعديل محتويات الذاكرة (تقنية Copy-on-Write)، مما يجعل fork أكثر كفاءة.

  • علاقة الأب والابن: العملية الوليدة ترث معظم بيئة التنفيذ الخاصة بالأب، لكن يمكن أن تختلف في بعض السمات مثل معرّف العملية.

  • الموارد المشتركة: العمليات الأب والابن تشاركان نفس الملفات المفتوحة، ولكن لكل عملية مؤشرات ملف خاصة بها.


استدعاء النظام Exec

بعد إنشاء العملية الوليدة بواسطة fork، غالبًا ما تحتاج هذه العملية إلى استبدال برنامجها الحالي ببرنامج جديد يتم تنفيذه. وهنا يأتي دور استدعاء النظام exec، الذي يُستخدم لتحميل برنامج جديد داخل سياق العملية الحالية.

ما هو exec؟

  • هو مجموعة من استدعاءات النظام التي تحل محل صورة العملية الحالية (Process Image) بصورة برنامج جديد.

  • عند تنفيذ exec، يتم تحميل برنامج جديد إلى ذاكرة العملية، ويتم استبدال الكود التنفيذي، البيانات، وذاكرة المكدس (stack) وغيرها ببيانات البرنامج الجديد.

  • بعد استدعاء exec، لا يعود البرنامج القديم موجودًا، وتتولى العملية تنفيذ البرنامج الجديد بدءًا من نقطة الدخول الخاصة به.

عائلة استدعاءات exec

هناك عدة دوال تنتمي إلى عائلة exec، من أشهرها:

  • execl

  • execv

  • execle

  • execve

  • execlp

  • execvp

وتختلف هذه الدوال في كيفية تمرير المعاملات والبيئة، لكن جميعها تقوم بنفس الوظيفة الأساسية وهي استبدال صورة العملية.


العلاقة بين Fork و Exec في تسلسل العمليات

في نظام التشغيل، يتم استخدام استدعائي fork و exec بشكل متسلسل لإنشاء عملية جديدة تنفذ برنامجًا مختلفًا عن البرنامج الأب.

الخطوات النموذجية

  1. إنشاء العملية الوليدة باستخدام fork: يقوم البرنامج الأصلي بإنشاء نسخة من نفسه.

  2. استبدال صورة العملية الوليدة بواسطة exec: في العملية الوليدة، يتم استدعاء exec لتحميل برنامج جديد.

  3. استمرار العملية الوليدة في تنفيذ البرنامج الجديد: تبدأ العملية الوليدة في تنفيذ التعليمات الخاصة بالبرنامج الذي تم تحميله حديثًا.

  4. استمرار العملية الأب في تنفيذ البرنامج الأصلي: العملية الأب تستمر في عملها المعتاد أو تنتظر انتهاء العملية الوليدة.

هذا التسلسل يسمح بفصل وظيفتين أساسيتين:

  • fork لإنشاء عملية جديدة.

  • exec لتشغيل برنامج مختلف في العملية الجديدة.


تفاصيل تقنية عن Fork و Exec

تأثير Fork على الذاكرة

عندما ينشأ استدعاء fork، يتم تكرار المحتوى الظاهر للذاكرة الخاصة بالعملية الأب. لكن بسبب التكلفة العالية للنسخ الكامل للذاكرة، تستخدم أنظمة التشغيل الحديثة تقنية Copy-on-Write (COW)، التي تؤجل نسخ صفحات الذاكرة حتى يتم تعديلها من قبل إحداهما (الأب أو الوليد).

تغيير صورة العملية بواسطة Exec

بعد تنفيذ exec، تتغير محتويات العملية تمامًا، لذا تُزال جميع مؤشرات الملفات المؤقتة، وتُعاد تهيئة المعالج والذاكرة، بينما يحتفظ النظام بمعرّف العملية (PID) الخاص بالعملية الأصلية. بهذا يمكن للعمليات تتبع تسلسل العمليات الهرمي دون تغييرات في المعرّفات.


التحكم في العمليات والهرمية الناتجة

عندما يتم إنشاء عملية جديدة باستخدام fork، تصبح العملية الجديدة تابعة للعملية الأب. من المهم أن يدير الأب العمليات الوليدة بشكل صحيح، خصوصًا في حالة وجود عدد كبير من العمليات الوليدة، لتجنب مشكلات مثل العمليات اليتيمة أو العمليات الزومبي.

العمليات الزومبي (Zombie Processes)

هي العمليات الوليدة التي انتهت من التنفيذ لكنها ما زالت تحتفظ بمدخل في جدول العمليات لأن الأب لم يستلم حالة خروجها بعد (لم يستدع wait). تراكم هذه العمليات يؤدي إلى استهلاك موارد غير ضرورية.

العمليات اليتيمة (Orphan Processes)

هي العمليات الوليدة التي أصبح الأب الخاص بها غير موجود (انتهى أو تم قتله). عادة ما يتم تبني هذه العمليات من قبل العملية init أو systemd، لضمان استمرارية إدارة العمليات بشكل صحيح.


جدول مقارنة بين Fork و Exec

الخاصية Fork Exec
الوظيفة إنشاء عملية جديدة (نسخة طبق الأصل) استبدال صورة العملية ببرنامج جديد
تأثير على الذاكرة نسخ بيئة العملية الأب (مع COW) تحميل برنامج جديد واستبدال الذاكرة
القيمة المرجعة في الأب: PID الوليد، في الوليد: 0 لا ترجع القيمة عند النجاح (تستمر العملية)
العلاقة بين العمليات علاقة أب-ابن (هرمية) لا تُنشئ عمليات جديدة، تغير محتوى العملية الحالية
استخدام شائع لإنشاء عمليات فرعية لتشغيل برامج جديدة داخل العملية الوليدة
الإطار التنفيذي العملية الأب والعملية الوليدة تعملان العملية تستمر كبرنامج جديد

خاتمة فنية حول استدعاء fork و exec في إدارة العمليات

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

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

من خلال هذا المقال تم تناول المفاهيم الأساسية والعمليات التقنية لاستدعاء fork و exec، وأهميتهما في تكوين التسلسل الهرمي للعمليات، مما يوفر رؤية عميقة تساعد في فهم بنية نظام التشغيل على مستوى العمليات وكيفية تفاعلها لتحقيق التزامن وتنظيم الموارد.


المراجع

  1. Tanenbaum, A. S., & Bos, H. (2015). Modern Operating Systems (4th Edition). Pearson.

    • مرجع أساسي لفهم مفصل لاستدعاءات fork و exec وكيفية إدارة العمليات في أنظمة التشغيل.

  2. Silberschatz, A., Galvin, P. B., & Gagne, G. (2018). Operating System Concepts (10th Edition). Wiley.

    • كتاب شامل يشرح مفاهيم العمليات واستدعاءات النظام مع أمثلة عملية وتوضيحات تفصيلية.