محمد مرهف الحمصي
11-23-2008, 02:09 PM
شكر جزيل للمهندسة ماجدة
المحاضرة الأولى
1مقدمة
الهدف من الفصل
يهدف هذا الفصل إلى تحصيل الأهداف والمعارف التالية:
إعطاء تعريف أولي لنظام التشغيل، يستند إلى الأدوار المختلفة للنظام.
إعطاء لمحة تاريخية عن أنظمة التشغيل وتطورها عبر الزمن.
استعراض الأشكال المختلفة لأنظمة التشغيل المستخدمة مع النقاط المميزة لكل منها.
1. ماهي أنظمة التشغيل؟
تطورت الإجابة على هذا السؤال بشكل ملموس خلال العقود التي تشكل فترة حياة الحاسوب .
ففي الستينات، كانت الإجابة هي "البرمجيات التي تتحكم بالتجهيزات ". أما في يومنا هذا، فهذه
الإجابة غير كافية، إذ تطور استخدام الحاسوب إلى درجة تجعل من الصعب إعطاء إجابة
دقيقة.
ويمكننا في البداية الاحتفاظ بهذا التعريف مع تطويره ليصبح على الشكل التالي:
نظام التشغيل هو مجموعة البرمجيات المسؤولة عن التحكم بعمل الموارد المختلفة في
الحاسوب، وتوزيعها على التطبيقات والمستخدمين بحسب حاجتها.
ونحن في هذا التعريف نبرز إحدى أهم المهام في أنظمة التشغيل : إدارة الموارد وتخصيصها .
وأهم هذه الموارد هي التجهيزات المتوضعة ضمن الحاسوب، من معالجات وذاكرة ووسائط
تخزين وتجهيزات للدخل والخرج وتجهيزات للاتصالات.
2. مهام نظام التشغيل
يهدف التصميم الحالي لأنظمة التشغيل إلى تأدية ثلاث مهام رئيسية:
إخفاء تفاصيل عمل التجهيزات عن المستخدم والتطبيقات:
إذ يشكل نظام التشغيل آلة افتراضية تحصر تعامل التطبيقات مع الموارد الحاسوبية المتختلفة
عبر واجهة برمجية عالية المستوى. وتعتمد في ذلك على الحد من العمليات التي يمكن
للتطبيقات أن تقوم بها مباشرة، وتزويدها عوضًا عن ذلك بعدد من التوابع التي يمكن
. للتطبيقات استدعاؤها ويقوم نظام التشغيل بتنفيذها 1
System calls 1 تسمى هذه الآلية باستدعاءات النظام
إن هذا المستوى العالي من التجريد مفيد جدًا للأسباب التالية:
إن البرمجيات المستخدمة للتحكم بالتجهيزات ليست معيارية بطبيعتها، وهي متنوعة
إلى حد كبير . ومن الصعب التعامل معها بدون وجود مستوى عال من التجريد . ومثال
على ذلك هو تجهيزات الدخل والخرج، التي غالبًا ما يكون التعامل معها عبر عمليات
.Open, Close, Read, Write, IOctl : برمجية يع رفها نظام التشغيل
هناك عدد من المفاهيم المجردة التي لا يوجد ل ها مقابل على مستوى التجهيزات،
ومثال على ذلك هو نظام الملفات الذي يهدف إلى إخفاء تفاصيل التعامل مع أقراص
التخزين والطرق المختلفة لتوضع البيانات ضمن هذه الأقراص عن التطبيقات.
يسمح هذا التجريد بإظهار الحاسوب للبرامج على شكل مجموعة حواسيب افتراضية،
وبحيث ينفذ كل برنامج على حاسوب افتراضي مستقل . ويسمى البرنامج قيد التنفيذ
وهي واحدة التنفيذ التقليدية في أنظمة التشغيل. ،Process بالإجرائية
إن التعامل الإلزامي مع الآلة الافتراضية لنظام التشغيل كطريق وحيد للتعامل مع
التجهيزات يسمح بفرض ضوابط الأمن الضرورية لحماية المس تخدمين وبياناتهم
وإجرائياتهم.
تخصيص الإجرائيات بالموارد التي تحتاجها:
وبذلك يكون نظام التشغيل .Resource Manager وهو دور نظام التشغيل كمدير للموارد
مسؤو ً لا عن حل التضارب في طلب الموارد وإدارتها بالشكل الأمثلي والتأكد من عدم استئثار
. إجرائيات بالموارد على حساب إجرائيات أخرى 2
حيث توزع الموارد ،Time Multiplexing يمكن لإدارة الموارد أن تعتمد مبدأ التوزيع الزمني
على الإجرائيات بالترتيب، كما يحصل عندما يوزع نظام التشغيل زمن المعالج على عدة
إجرائيات، ويقوم بتبديل الإجرائية كلما انقضت مدة زمنية معينة . يمكن أن يكو ن التوزيع أيضًا
بحيث تحصل كل إجرائية على جزء من المورد، كما ،Space Multiplexing بحسب المكان
هو الحال في إدارة الذاكرة التي تقسم إلى أجزاء تحجز لصالح الإجرائيات.
Starvation 2 وهو ما يعرف بالمجاعة
تزويد المستخدمين بواجهة تخاطبية:
تسمح لهم بتوجيه طلباتهم إلى نظام التشغيل بالشكل الأنسب وا لأكثر تلبية لمتطلباتهم . وفي
كثير من الأحيان تكون هذه الواجهة عنصرًا أساسيًا في اختيار المستخدم لنظام التشغيل،
لاسيما في حالة الحواسيب الشخصية . وتحتوي هذه الواجهة التخاطبية على العديد من
المكونات، وأهمها:
تقديم المعونة للمستخدم.
متصفح نظام الملفات.
تزويد التطبيقات البرمجية المختلفة بواجهة
. موحدة تحوي العديد من الوظائف المعيارية 3
3. التطور التاريخي لأنظمة التشغيل
تطور استخدام الحواسيب بشكل حاد خلال الفترة الفاصلة بين بداية استخدامها وعصرنا
الحالي. وكانت قيمة تجهيزات الحاسوب وكلفة صيانته في البداية أكبر بكثي ر من كلفة اليد
العاملة اللازمة لتشغيله واستثماره، ولذلك كان الهدف الأساسي لأنظمة التشغيل في ذلك الحين
هو السماح لأكبر عدد ممكن من المستخدمين والتطبيقات باستخدام موارد الحاسوب في آن
واحد، وذلك بهدف توزيع الكلفة المرتفعة للتجهيزات على أكبر
عدد من الجهات المستفيدة.
أما في الوقت الراهن، فقد انعكست الآية، وصارت كلفة اليد
العاملة لمستثمري الحاسوب أكبر بكثير من ثمنه، ولم تعد كلفة
محطة تشغيل متطورة عالية الأداء تتجاوز الراتب الشهري
للشخص الذي يستخدمها في حال كان ذلك الاستخدام من السوية
الاحترافية. وبناء عليه، فقد بات التوجه الأساسي في أنظمة التشغيل هو المستخدم وضمان
راحته، وتسهيل استخدامه للحاسوب ورفع انتاجيته إلى
أقصى مايمكن.
هناك العديد من الوظائف الموجودة في أنظمة التشغيل
تعود إلى أكثر من ثلاثين سنة خلت، بينما هناك
مفاهيم أخرى لم تظهر إلا خلال السنوات الخمس
الأخيرة. وهي كلها وظائف مهمة وأساسية ولايمكن الاستغناء عنها، ومن المفيد الاطلاع على
3 مثل قوائم الملفات والتحرير
التطور التاريخي لأنظمة التشغيل لفهم هذه الوظائف وسياق ظهورها وأهمية وجودها.
المرحلة الأولى لأنظمة التشغيل (سنوات الخمسينات)
كانت الحواسيب في البداية مكلفة جدًا، وكانت نفقات ص يانتها وتشغيلها هائلة، وكان التعامل
معها يجري باستخدام واجهة تخاطبية نصية يمكن لمستخدم وحيد استخدامها في لحظة ما .
وكان المبرمجون يتعاملون مع الحواسيب
باستخدام آليات من سوية منخفضة جدًا،
كتلقيم البطاقات المثقبة.
وكان الدور الأساسي لما يمكن تسميته
نظام تشغي ل في تلك الفترة هو القيام
بالمهام التالية:
إدارة تجهيزات الدخل والخرج،
ولاسيما كتابة برمجيات القيادة لتلك التجهيزات التي كانت معقدة جدً ا. وأخذت هذه البرمجيات
شكل مكتبة مشحونة في الذاكرة الأساسية بشكل دائم.
تكثيف عدد مستخدمي الحاسوب الذي كان يقضي وقتًا طوي ً لا بدون عمل بينما كان
المبرمجون يقومون بشحن برامجهم . وكتبت لهذا الغرض العديد من البرمجيات التي كانت
مهمتها شحن التطبيقات مسبقًا على قرص صلب أو أشرطة ممغنطة، ومن ثم طلب تشغيلها
بشكل تلقائي ومتتابع.
المرحلة الثانية (الستينات)
ظهرت العديد من النقاط الهام ة نتيجة محاولة تكثيف استخدام الحاسوب وموارده، ومنها العمل
وذلك بهدف استغلال الوقت الضائع .Multiprogramming على تشغيل عدة برامج في آن واحد
الذي تقضيه البرامج في عمليات الدخل والخرج دون أن تستخدم وحدة المعالجة . وكان
التصور الأولي مبنيًا على تقسيم الذاكرة الم ركزية إلى
عدة أجزاء، يحوي ك ً لا منها برنامجًا، ويقوم نظام التشغيل
بالتبديل بينها بهدف إبقاء وحدة المعالجة تعمل باستمرار.
والمقصود بها هي وضع تجهيزات تسمح ،spooling ظهرت أيضًا وظيفة هامة معروفة باسم
بإجراء عمليات دخل وخرج بسرعة مرتفعة (نسبيًا) بين التطبيقا ت وبين تجهيزات الدخل
والخرج البطيئة، وهي وظيفة لاتزال
مستخدمة حتى يومنا هذا. إذ لاتقوم
التطبيقات بطباعة الملفات مباشرة إلى
الطابعة، بل تقوم بتوليد ملف محفوظ على
القرص الصلب وتتابع عملها وكأنها انتهت،
ويقوم نظام التشغيل بمتابعة عملية الطباعة.
وفي سعيها لتكثيف عدد المستخدمين
المتصلين على الحاسوب، أضافت أنظمت
وهي آلية مطورة من تعدد .Time sharing التشغيل آلية شديدة الأهمية هي تقاسم الزمن
البرامج المذكور سابقًا، وتسمح بتزويد كل مشترك يعمل على الحاسب بطرفية مستقلة متصلة
إلى الحاسب . تستخدم هذه الطرفي ة لإدخال الأوامر ومتابعة التنفيذ وقراءة النتائج بشكل تفاعلي
ويقوم نظام التشغيل بالتبديل بين البرامج التي تعمل بسرعة كافية لإعطاء .(Interactive)
المستخدم الانطباع أنه يعمل على الحاسب لوحدة ولايشاركه فيه أحد.
ونتيجة لتقاسم الزمن بين المستخدمين ظهرت الحاجة إل ى حماية التطبيقات التي تعمل في آن
. واحد من بعضها البعض، إذ لايجوز أن يؤثر تطبيق على تطبيق آخر 4
المرحلة الثالثة (الثمانينات)
مع ظهور الدارات والرقاقات المدمجة على نطاق واسع، وبالتحديد المعالجات الصغرية التي
كانت قادرة على تقديم سرعة معالجة تكافئ الحواسيب ا لكبيرة في سنوات السبعينات، دخلت
أنظمة التشغيل مرحلة الحواسيب الشخصية، مع التركيز على تفاعلية المستخدم مع الحاسوب
وحصوله على النتيجة بسرعة مقبولة . وهنا ظهرت مفاهيم جديدة كالجدولة التبديلية التي تهدف
إلى زيادة التفاعلية وعدم السماح لتطبيق ما بالاستئثار بوحدة المعالجة
لفترة طويلة.
4 مع هذه الوظائف المختلفة، بدأت أنظمة التشغيل تأخذ جزءًا من الشكل الذي نعرفه اليوم، وتحولت
بدورها إلى مستهلك لموارد الحاسوب لايستهان به.
ظهرت أيضًا الحاجة إلى تخزين البيانات والبرمجيات اللازمة لعمل المستخدمين وإتاحة
الوصول إليها بشكل مريح كبديل عن البطاقات المثقبة والأشرطة
،(File System) الممغنطة، وأدى هذا إلى ظهور نظام إدارة الملفات
بالإضافة إلى مفهوم خصوصية بيانات المستخدمين وحمياتها من
بعضهم البعض.
وربما كان الحدث الأهم هو بداية ظهور الواجهة التخاطبية مع الثورة التي أطلقتها أجهزة
ماكنتوش من شركة آبل، والتي غيرت بدون أدنى شك من وجه الحوسبة في العالم أجمع .
وباتت دعايات الحواسيب تركز على مدى راحة المستخدم في التعامل مع الحاسوب ورغبته
في الاستمرار بالعمل عليه، وليس على معايير السرعة البحتة التي كانت شائعة قب ً لا.
المرحلة الرابعة (التسعينات وحتى الآن)
أصبحت الحواسيب الشخصية متاحة لكل الناس تقريبًا، ونمت حاجة المستخدمين لتبادل
المعلومات، وظهرت الشبكات كأداة
فعالة وأساسية في هذا التبادل .
واعتبارًا من النصف الثاني من
عقد التسعينات، لم يعد من الممكن
الحديث عن نظام تشغيل لايدعم
الوصل مع شبكة الإنترنت
باعتبارها أكبر مصدر للمعلومات
في العالم . وحمل ذلك في طريقه
العديد من الأفكار التي انعكست
مباشرة على نظام التشغيل، الذي لم يعد مج رد واجهة تسمح بالتخاطب مع تجهيزات
الحاسوب، بل أعيدت هيكلة النظام ليسمح بالتخاطب مع الشبكة والحواسيب والموارد وظهر
والتي غالبًا ما يكون دورها هو تأمين واجهة ،middleware مفهوم البرمجيات الوسيطة
برمجية تخفي تفاصيل الشبكة عن التطبيقات والمبرمجين، وتسمح بكتابة تطبيقات موزعة على
Java Virtual عدة حواسيب، وأحد أشهر هذه البرمجيات الوسيطة هي آلة جافا الافتراضية
.Machine
4. الأشكال المختلفة لأنظمة التشغيل
،WindowXP : لو سألنا مستخدمي الحاسوب عن أنظمة التشغيل التي يعرفونها، لأجاب أغلبهم
ولكن هذه الإجابات لاتمثل إلا الحد الأدنى من أنظمة التشغيل المتاحة فع ً لا ،Linux وربما
والمستخدمة في الكثير من الحالات التي قد لانراها مباشرة.
أنظمة تشغيل الحواسيب العملاقة
لاتزال الحواسيب العملاقة حاضرة بقوة في مراكز البيانات الخاصة بالشركات الكبرى 5، وهي
تتميز بقدرتها الهائلة على ا لتعامل مع كميات كبيرة جدًا من معلومات الدخل والخرج . ومن
الممكن ان تحوي هذه الحواسيب على مئات الأقراص الصلبة وآلاف الجيجا بايت من سعة
التخزين. وتستخدم هذه الحواسيب أيضًا كمخدمات للويب وتطبيقات التجارة الإلكترونية
.B2B وعمليات التبادل التجاري بين الشركات
تتخصص أنظمة التشغيل لهذه الحواسيب في معالجة العديد من البرامج بآن واحد، وهذه
البرامج تستهلك الكثير من عمليات الدخل والخرج.
وتميز عادة بين ثلاثة أنواع من الخدمات:
التي لاتقوم بأي تبادل تفاعلي مع المستخدم : ومثال عليها هي batch خدمات الأعمال
معالجة عمليات المب يعات في سلسلة من المخازن وارتباطها مع حركة المستودعات . وهي
عمليات تحتاج إلى وقت طويل.
وهي عبارة عن عدد كبير من العمليات الصغيرة، :Transaction خدمات المناقلات
كمعالجة الشيكات في مصرف، حيث تكون العمليات بسيطة جدًا ولكن هناك عدد كبير جدًا
منها يقدر بالمئات أو الآلاف في الثانية.
خدمة تقاسم الوقت: التي تسمح لعدة مستخدمين باستثمار الحاسوب في نفس الوقت.
.OS/ وهو وريث للنظام 360 ،OS/ ومن أهم الأمثلة لهذه الأنظمة هو النظام 390
5 لاسيما الشركات المالية والمصارف
أنظمة تشغيل المخدمات
إن كلمة "مخدم" تتضمن تعريفًا وظيفيًا للمخدمات بغض النظر عن حجمها، وإن درجت العادة
ان تكون المخدمات عبارة عن حواسيب كبيرة. والمخدم هو:
حاسوب يقوم بتقديم خدمات للزبائن الذين يرسلون طلباتهم عبر اتصال شبكي، كمخدم
الوب ومخدم البريد الإلكتروني ومخدم الملفات.
.Linux و ،Window 2003 Server ومثال على أنظمة تشغيل المخدمات
أنظمة التشغيل متعددة المعالجات
إن إحدى أكثر الطرق شيوعًا لزيادة سرعة الحواسيب هي وصل عدة وحدات معالجة ضمن
نظام واحد، وغالبًا ما يستخدم ذلك في المخدمات . وبالتالي تكون أنظمة التشغيل التي تتعامل
مع هذه المعالجات المتعددة هي نسخة متخصصة من نظام تشغيل المخدم.
أنظمة تشغيل الحواسيب الشخصية
تركز هذه الأنظمة على تزويد المستخدم بواجهة تخاطبية ملائمة، وهي مستخدمة على نطاق
واسع في التطبيقات المكتبية والنفاذ إلى الإنترنت . ومن أشهر الامثلة نظام ويندوز بنسخه
المختلفة (باستثناء نسخ المخدم )، ونظام ماكينتوش ولينوكس . وهذه الأنظم ة معروفة إلى درجة
أن أغلب المستخدمين قد لايعرفوا غيرها.
أنظمة التشغيل بالزمن الحقيقي
هذه الأنظمة تعتمد على الزمن كعامل أساسي في عملها . فعلى سبيل المثال، يمكن أن تستخدم
هذه الأنظمة في التحكم بالإجرائيات الصناعية حيث يتم جمع معلومات عن عملية الإنتاج
يجب deadlines واستخدامه للتحكم بالآلات في المعمل . وغالبًا ما تكون هناك أزمنة حدية
الالتزام بها.
فإذا أخذنا منظومة التحكم بحركة عربة ضمن سلسلة الإنتاج والذراع التي تنقل العربة، فلو
أفلتت الذراع العربة قبل أو بعد اللحظة المناسبة بفارق زمني يتجاوز حد التسامح ستتعرض
العربة إلى ضرر بالغ . وهنا نتكلم عن منظومة بالزمن الحقيقي القاسي إذ يجب أن ترسل
. المنظمة أوامرها في لحظة معينة، وليس قبل أو بعد هذه اللحظة 6
أنظمة التشغيل المحمولة
وهي المسؤولة عن التحكم بعمل الحواسيب الصغيرة جدًا والأنظمة المحمولة التي لا تعتبر
بالضرورة حو اسيب، كأجهزة التلفزيون والهواتف المحمولة . وغالبًا ما تكون لهذه الأنظمة
نفس متطلبات أنظمة التشغيل بالزمن الحقيقي، ولكن لديها أيضًا ضوابط الحجم والذاكرة
و PalmOS واستهلاك القدرة التي تجعل منها أنظمة خاصة . ومن أهم أنظمة التشغيل هذه
.Windows CE
نهاية الوحدة
6 هناك أيضًا أنظمة الزمن الحقيقي اللينة، والتي يمكن أن تتقبل حصول خطأ من وقت لآخر،
.VxWorks و QNX كأنظمة التحكم بنقل الصوت والصورة. ومن أشهر أنظمة الزمن الحقيقي
المحاضرة الثانية
1
بنى نظم التشغيل
الهدف من الفصل
يهدف هذا الفصل إلى تحصيل الأهداف والمعارف التالية:
التعريف بالخدمات التي تقدمها أنظمة التشغيل للمستخدمين
التعريف باستدعاءات النظام كأداة أساسية لطلب هذه الخدمات
التعريف ببرمجيات النظام كمجموعة أدوات أساسية للمستخدم
مناقشة الطرق المختلفة لتصميم نظام التشغيل
1. خدمات نظام التشغيل
يقدم نظام التشغيل العديد من الخدمات للبرمجيات ومستخدميها، وذلك بهدف مساعدتهم على
استخدام الموارد الحاسوبية بشكل أمثل . وتشمل المجموعة الأولى من الخدمات تلك التي تسمح
للمستخدمين بالتعامل مع المنظومة الحاسوبية.
User Interface المجموعة الاولى: الواجهة التخاطبية
تقدم جميع أنظمة التشغيل واجهة تخاطبية لمستخدميها تسمح لهم بتوجيه الأوامر للنظام والتعامل
(GUI: Graphical User Interface) مع خدماته المختلفة. وقد انتشرت الواجهات التخاطبية البيانية
منذ سنوات التسعينات وتطورت تدريجيًا حتى باتت جزءًا لايتجزأ من نظام التشغيل، لاسيما في
حالة محطات العمل والحواسيب الشخصية.
وتتدرج أهمية الواجهة التخاطبية البيانية في نظام التشغيل من الحالة القصوى حيث يستحيل
القيام بأية عملية بدونها كما هو الحالي في نظام ماكينتوش الذي كان أول من أطلق هذا النوع
من الواجهات، مرورًا بنظام ويندوز بأشكاله المختلفة الذي يعتمد أساسًا على هذه الواجهات
ولكنه يدعم أيضًا الواجهة التقليدية التي تعتمد على الأوامر النصية المتكوبة
ووصو ً لا إلى أنظمة تفصل كليًا بين هذه الواجهة ونظام ،(CLI : Command Line Interface)
التشغيل، وتسمح للمستخدم بأن يتعامل مع النظام ويستخدم كافة خدماته بدون استثناء دون
بأشكاله المختلفة. Unix المرور بالواجهة البيانية، مثل نظام
Program Execution المجموعة الاولى: تنفيذ البرامج
إن الهدف الأساسي للمستخدم من استخدام الحاسوب هو تنفيذ البرامج والتطبيقات التي يحتاج
إليها، كمعالجات النصوص وبرامج الرسم ومعالجة الصورة . ويجب أن يسمح نظام التشغيل
2
التي (Parameters) للمستخدم بتحديد البرنامج الذي يرغب في استخدامه، وتحديد الوسائط
يرغب في تمريرها له، وطلب تنفيذ البرنامج وإيقاف تنفيذه، سواء كان ذلك نتيجة ا نتهاء طبيعي
للبرنامج أو نتيجة انتهاء قسري ناتج عن طلب المستخدم أو خطأ في التنفيذ . ويجب أن يعرف
المستخدم ما هي نتيجة تنفيذ البرنامج وماهو الخطأ في حال وجوده.
I/O Operations المجموعة الاولى: عمليات الدخل والخرج
هذه العمليات هامة جدًا، إذ أنها تسمح للبرنامج ب الاتصال مع العالم الخارجي والحصول على
المعلومات اللازمة لتنفيذها وإظهار النتائج المطلوبة . ومنها قراءة المحارف من لوحة الملامس
أو عبر البوابة التسلسلية أو قراءة البيانات الواردة عن طريق بطاقة الشبكة، أو إرسال معلومات
للطباعة.
File-system manipulation المجموعة الاولى: التعامل مع نظام الملفات
يعتبر نظام الملفات أحد أهم مكونات نظام التشغيل، وذلك لأنه المسؤول الأساسي عن التعامل مع
والتي يتجاوز عمرها عمر البرنامج الذي أنشأها أو قام بتعديلها . ،persistent البيانات الدائمة
ويحتاج المستخدم إلى التمكن من إنشاء الملفات وحذفها، وقراءة محتواها وتعديلها وحفظ هذه
التعديلات. وقد تكون هناك حاجة لتحديد سماحيات الاستخدام وفرض هذه السماحيات على
التطبيقات المختلفة ولاسيما في الأنظمة متعددة المستخدمين.
Communications المجموعة الاولى: الاتصال
تحتاج التطبيقات إلى تأمين الاتصال فيما بينها، سواء إن كانت تعمل على الحاسوب نفسه أو
على حواسيب مختلفة متصلة عن طريق شبكة، كما هو الحال في تطبيقات الإنترنت وتصفح
الوب. ويمكن أن يكون الاتصال عبر ذاكرة مشتركة، أو عن طريق تبادل الرسائل.
Error detection المجموعة الاولى: اكتشاف الأخطاء
يجب أن يكون نظام التشغيل قادرًا باستمرار على اكتشاف الأخطاء التي قد تحصل في الأجزاء
المختلفة من المنظومة الحاسوبية . قد تكون الأخطاء عتادية، كتلك الناتجة عن ارتفاع درجة
حرارة المعالج أو تآكل الأجزاء الداخلية للقرص الصلب أو تعرض الدارات الإلكترونية للغبار .
ويمكن أن تكون الأخطاء برمجية، كتلك الناتجة عن خطأ في عنونة الذاكرة او محاولة فتح ملف
غير موجود . ويجب أن يتخذ نظام التشغيل الخطوات اللازمة لاكتشاف الأخطاء وتشخيصها
وإعلام الشخص المسؤول (عادة يكون هناك مدير للنظام ) عن معالجة هذه الأخطاء وإصلاحها .
وذلك بهدف السماح Debugging وتقدم أنظمة التشغيل عادة خدمة التنفيذ في حالة الاختبار
3
للمبرمجين ومطوري التطبيقات باكتشاف أكبر قدر ممكن من هذه التطبيقات قبل إرسالها
للزبائن.
أما المجموعة الثانية من الخدمات فتهدف إلى زيادة فاعلية استخدام موارد الحاسوب :
المجموعة الثانية: تخصيص الموارد
ويقصد بذلك إدارة الموارد المتاحة والمتنوعة ضمن الحاسوب كزمن المعالج وذاكرة التنفيذ
وبوابات الدخل والخرج . وتتميز هذه الموارد بمحدوديتها مما ينتج عنه استحالة تخصيص كافة
التطبيقات التي تنفذ في نفس الوقت بكل ما تطلب . ولذلك تتسم هذه الخدمة بأهمية خاصة، إذ يقع
على عاتقها إدارة عملية التخصيص للموارد المختلفة وتلافي الأزمات التي يمكن أن تنتج عن
سوء الإدارة.
المجموعة الثانية: المحاسبة
ويقصد بذلك توليد المعلومات اللازمة لمعرفة حجم استهلاك المستخدمين للموارد المختلفة ضمن
المنظومة الحاسوبية.
المجموعة الثانية: الحماية والأمن
وهي خدمات ضرورية بسبب وجود عدة مستخدمين يستخدمون الحاسوب ومواردة في آن واحد .
والهدف هو حماية البرامج التي تنفذ وبيانات المستخدمين من التعديات المقصودة أو غير
المقصودة. وتنقسم بدورها إلى فئتين من الخدمات :
الحماية: ويقصد بها التأكد من أن التعامل مع مكونات النظام العتادية والبرمجية يمر دومًا
عبر آليات تحكم تمنع حصول نتائج غير مرغوبة . فعلى سبيل المثال، في حال السماح
للتطبيقات بالتعامل المباشر مع التجهيزات، يمكن للبرامج إصدار أوامر لدارات التحكم
بالقرص الصلب من شأنها مسح محتواه، وهذا ماكانت تقوم به الف يروسات لفترة طويلة عندما
لم يكن نظام التشغيل يقدم هذه الحمايات . ولاتقتصر أهمية الحماية على التخريب المتعمد، بل
يمكن ان يكون هناك تخريب غير متعمد.
إذ يمكن للمبرمج أن يحاول .C كالذي ينتج عن أخطاء العنونة الشائعة جدًا بين مبرمجي لغة
استخدام مؤشرات غير مؤسسة، وبالتالي تشير إلى مناطق عشوائية من الذاكرة، وفي حال
السماح بتنفيذ هذه العمليات يمكن أن يكتب البرنامج في مساحات الذاكرة الخاصة ببرامج
اخرى أو بنظام التشغيل . وكان هذا النوع من الأخطاء يؤدي عادة في أنظمة التشغيل التي
إلى توقف النظام عن العمل والحاجة إلى إعادة (Win و 95 Win لاتدعم الحماية إلى (مثل 311
الإقلاع.
الأمن: والمقصود بذلك التحقق من هوية المستخدمين الذين يرغبون في استخدام موارد
4
النظام وحصر التعامل مع هذه الموارد بالمستخدمين المخولين بذلك، وقد يتضمن ذلك أيضًا
الاحتفاظ بسجلات الولوج إلى النظام بهدف اكتشاف محاولات الاختراق الفاشلة ومصدرها.
System calls 2. استدعاءات النظام
تشكل هذه الاستدعاءات الطريقة الأساسية لطلب خدمات نظام التشغيل، وهي غالبًا ما تكون
عالية السوية API متاحة للمبرمجين ومطوري التطبيقات على شكر واجهة لبرمجة التطبيقات
ومن أشهر هذه الواجهات البرمجية : .C++ او C ومكتوبة بلغة برمجة مثل
المستخدم في نظام ويندوز Win32
المستخدم في أغلب أنظمة يونيكس وليونكس ونظام تشغيل ماكنتوش POSIX
Mac OSX
.JVM التي تسمح بالتخاطب مع آلة جافا الافتراضية Java الواجهة البرمجية للغة
لاستدعاءات النظام خصوصية هامة، وهي أنه ا في أغلب الأحيان تسمح للإجرائيات بتنفيذ
تعليمات خاصة غير متاحة عادة للبرمجيات . وسبب ذلك هو أن أغلب وحدات المعالجة تعمل
بحالتين :
وتكون فيها كافة التعليمات مسموحة ومستخدمة. :Kernel Mode حالة النواة
التي تكون فيها تعليمات الدخل والخرج والتعامل مع :User Mode حالة المستخدم
بعض السجلات الحرجة غير مسموحة.
وقد جرى اعتماد هاتين الحالتين بهدف تحقيق الحماية التي تكلمنا عنها في المقطع، وتشكل
استدعاءات النظام عادة نقطة عبور بين هاتين الحالتين.
الحماية: ويقصد بها التأكد من أن التعامل مع مكونات النظام العتادية والبرمجي ة يمر دومًا عبر
آليات تحكم تمنع حصول نتائج غير مرغوبة . فعلى سبيل المثال، في حال السماح للتطبيقات
بالتعامل المباشر مع التجهيزات، يمكن للبرامج إصدار أوامر لدارات التحكم بالقرص الصلب من
شأنها مسح محتواه، وهذا ماكانت تقوم به الفيروسات لفترة طويلة عندما لم يكن نظام التشغيل
يقدم هذه الحمايات . ولاتقتصر أهمية الحماية على التخريب المتعمد، بل يمكن ان يكون هناك
تخريب غير متعمد.
تصنف استدعاءات النظام بحسب الفئات التالية:
التحكم بالإجرائيات، والمقصود بذلك كافة العمليات المتعلقة بتنفيذ البرامج.
إدارة الملفات.
5
إدارة التجهيزات.
إدارة البيانات.
الاتصالات.
ReadFile ويظهر المثال التالي شكل أحد التوابع من واجهة برمجة نظام ويندوز وهو التابع
المستخدم في قراءة بيانات من ملف مفتوح :
BOOL ReadFile(
HANDLE hFile,1
LPVOID lpBuffer,2
DWORD nNumberOfBytesToRead,3
LPDWORD lpNumberOfBytesRead,4
LPOVERLAPPED lpOverlapped5
);
انقر على كل من الكلمات الملونة ضمن السطور البرمجية لترى التوضيح.
إذ تسمح للمبرمجين بكتابة استدعاءات النظام وكأنهم API إن الواجهة البرمجية للنظام مفيدة جدًا
عاديًا، وبدون أن يعرفوا تفا صيل تنفيذ هذه الاستدعاءات، ولو لم Procedure يستدعون إجرا ء
تكن هذه الواجهة موجودة، لكان على المبرمج أن يلم بتفاصيل عديدة، مثل رقم الاستدعاء،
والسجلات المستخدمة لحفظ الوسائط . وغالبًا ما تقدم هذه الواجهة على شكل مكتبة برمجيات
بالإضافة إلى مكتبات التنفيذ اللازمة. ،Compiler ملحقة بالمترجم
المذكور أعلاه 6. ونلاحظ العبور ReadFile ويظهر الشكل آلية استدعاء وتنفيذ استدعاء النظام
بين حالتي التنفيذ المستخدم والنواة بفضل استخدام استدعاء النظام.
الملف الذي نريد القراءة منه : file 1
خزان يستخدم في حفظ البيانات التي ستقرأ من الملف : lpBuffer 2
عدد المحارف المطلوب قراءتها : nNumberOfBytesToRead 3
عدد المحارف المطلوب التي تمت قراءتها فعليًا. :lpNumberOfBytesRead 4
معلومات تستخدم فقط في حال كون قراءة الملف غير متزامنة، أي أن التابع : lpOverlapped 5
ينهى عمله ويعيد النتيجة دون أن ينتهي بالضرورة من قراءة كل المحارف المطلوبة. ReadFile
6 BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
6
لاستدعاءات النظام خصوصية هامة، وهي أنها في أغلب الأحيان تسمح للإجرائيات بتنفيذ
تعليمات خاصة غير متا حة عادة للبرمجيات . وسبب ذلك هو أن أغلب وحدات المعالجة تعمل
بحالتين :
وتكون فيها كافة التعليمات مسموحة ومستخدمة. :Kernel Mode حالة النواة
التي تكون فيها تعليمات الدخل والخرج والتعامل مع :User Mode حالة المستخدم
بعض السجلات الحرجة غير مسموحة.
تختلف أنظمة التشغيل بين بعضها البعض في طريقة تمرير الوسائط لاستدعاءات النظام، وتوجد
حاليًا ثلاث آليات مختلفة لتمرير الوسائط :
استخدام السجلات لتمرير الوسائط، وهذه الطريقة هي الأبسط
تخزين السجلات ضمن مساحة معينة في الذاكرة، وتمرير عنوان هذه المساحة كوسيط .
.Linux و Solaris هذه الطريقة هي المعتمدة في نظامي
استخدام المكدس لتمرير الوسائط، مثل أي استدعاء لإجراء عادي، بحيث يقوم البرنامج
المستدعي بوضع الوسائط على المكدس ويقوم نظام التشغيل بسحبها من المكدس.
ورغم كون الطريقة الأولى الأبسط، فإن ها غير ملائمة بسبب محدو دية عدد السجلات، أما
7
الطريقتان الثانية والثالثة فلاتفرضان حدودًا على عدد الوسائط التي يمكن استخدامها . ويظهر
الشكل التالي آلية عمل الطريقة الثانية:
3. برمجيات النظام
يتكون رأي المستخدم في النظام الذي يتعامل معه عادة عبر استخدامه لبرمجيات النظام، وليس
عبر معرفته لاستدعاءات النظام التي لايتعامل معها إلا قلة من المبرمجين . ويمكن تصنيف هذه
البرمجيات ضمن الفئات التالية :
التعامل مع الملفات : وهي البرمجيات المسؤولة عن إجراء العمليات الأساسية الخاصة
بالملفات، من إنشاء وحذف ونسخ وإعادة تسمية واستعراض وطباعة محتوى بالإضافة
،Windows في نظام Explorer إلى التعامل مع المجلدات . ومثال عليها برنامج المتصفح
.Unix في نظام shell والتعليمات الخاصة بالملفات التي يوفرها مفسر الأوامر
حالة النظام : وهي البرمجيات المسؤولة عن تقديم المعلومات الخاصة بحالة النظام
كالوقت المنقضي منذ الإ قلاع، وحجم الذاكرة المتاح، وعدد المستخدمين الذي يعملون في
لحظة ما، وعدد البرامج التي تنفذ، ونسبة استخدام وحدة المعالجة، وبعض هذه البرامج
تقدم عرضًا مفص ً لا لمعلومات الأداء.
تحرير وتعديل الملفات : وهي البرمجيات المسؤولة عن تحرير الملفات والتعامل مع
التي grep وأداة ،Unix المستخدم في نظام vi محتواها، م ثل محرر النصوص الشهير
تسمح بإجراء عمليات البحث عن نص ضمن الملف.
8
أدوات البرمجة والاختبار : ويقصد بذلك كافة الأدوات اللازمة لتحويل البرامج من حالة
لغة المصدر إلى لغة الآلة . كالمترجمات, وبرمجيات الربط، وبرمجيات التحقق من
والتي تستخدم سواء على مستوى لغة البرمجة أو لغة الآلة . ،debuggers التنفيذ
وتتضمن هذه البرمجيات عادة المكتبات التي تسمح بكتابة استدعاءات النظام بسهولة.
الاتصالات: وهي البرمجيات التي تسمح بتبادل المعلومات بين البرامج التي تنفذ، كأن
يقوم المستخدم بإرسال رسا لة تظهر على شاشة مستخدم آخر . ويتجاوز مدى عمل هذه
البرمجيات الحاسب الواحد، فهي مسؤولة أيضًا عن الخدمات الشبكية، كإرسال البريد
.FTP الإلكتروني، وتصفح الوب، وسحب ملف من مخدم
4. التصميم العام لنظام التشغيل
لايوجد في الحقيقة وصفة جاهزة أو تصميم موحد لأنظمة الت شغيل، ولكن هناك عدد من القواعد
العامة للتصميم تكونت عبر الزمن، ويمكن القول أن تطبيق هذه القواعد يزيد من فرص الوصول
إلى نتائج جيدة إلى حد كبير . والقاعدة الأساسية هي البدء بتحديد المتطلبات، التي يمكن تقسيمها
إلى فئتين:
متطلبات المستخدمين : يجب أن تكون أنظمة ا لتشغيل سهلة الاستخدام والتعلم، عالية
الوثوقية، آمنة وسريعة.
متطلبات النظام : يجب أن تكون الأنظمة سهلة التصميم، والتحقيق والصيانة، بالإضافة
إلى تحقيق شروط المرونة والوثوقية والخلو من الأخطاء والفاعلية.
غالبا ما يتبع تصميم نظام التشغيل مبدأ الطبقات، بحيث تقد م كل طبقة عددًا من الخدمات للطبقة
التي تعلوها، وتستفيد بدورها من خدمات الطبقة الأدنى . وبحسب هذا المبدأ، تكون الطبقة الدنيا
والطبقة العليا هي طبقة واجهة التخاطب مع ،Hardware هي طبقة التجهيزات أو العتاديات
المستخدم.
ويظهر الجدول التالي ترتيب
،THE الطبقات في نظام التشغيل
وهو نظام تشغيل تجريبي بني في
عام 1968 ، ويتكون من ستة
طبقات مرقمة من الصفر حتى
الخمسة.
9
السوية الأولى (رقم صفر ): مسؤولة عن إدارة توزيع وحدة المعالجة والتبديل بين الإجرائيات
عند حصول مقاطعة زمنية . وبذلك كان بإمكان السويات التي فوقها أن تتعامل مع النظام على
أنه مكون من عدد من الإجرائيات التي تعمل بآن واحد.
السوية الثانية : مسؤولة عن إدارة الذاكرة، فقد كانت تقوم بتخصيصي الذاكرة للإجرائيات ضمن
الذاكرة المركزية، بالإضافة إلى ذاكرة تخزين من 512 ألف كلمة كانت تستخدم لحفظ أجزاء
الإجرائيات التي ليس لها مكا ن في الذاكرة المركزية . وبنتيجة ذلك، لم تكن الإجرائيات فوق
السوية رقم 1 تحتاج إلى التفكير إذا كانت مخزنة في الذاكرة المركزية أو ذاكرة التخزين.
السوية الثالثة والرابعة : مسؤولة عن معالجة الاتصالات بين كل إجرائية وشاشة المشغل، بحيث
كانت تعتقد كل إجرائية تعمل فوق هذه الطبقة بأن لديها شاشة إظهار خاصة بها.
السوية الخامسة : هي السوية التي تعمل ضمنها برمجيات المستخدمين وتستخدم خدمات
الإجرائيات والذاكرة والشاشة المقدمة من قبل السويات الأدنى.
السوية السادسة: تحوي على إجرائية مشغل النظام.
.Unix مثال( 1): نظام التشغيل يونيكس
كان نظام التشغيل يونيكس مسيطرًا على سوق محطات العمل والمخدمات طوال فترة الثمانينات
وحتى منتصف التسعينات . وذلك بوصفه نظامًا عالي الوثوقية، متعدد المهام ومتعدد
المستخدمين، ولم يكن له فعليًا أي منافس خلال هذه الفترة . وقد كان البنيان الأساسي لنظام
يونيكس محدودًا بجزئين فقط كما يظهر في الشكل التالي : (انقر على الصورة المجاورة لترى
النسخة المكبرة)
10
.Unix مثال: نظام التشغيل يونيكس
برمجيات النظام : وهي برمجيات تعمل في سوية المستخدم 7، وتضم الواجهة التخاطبية بأشكالها
المختلفة (بيانية، نصية )، بالإضافة إلى أدوات ال برمجة والتطوير ومحرر النصوص وأدوات
معالجة الملفات.
نواة النظام : وهي الطبقة التي تعلو التجهيزات مباشرة ومسؤولة عن تحقيق عدد كبير جدًا من
الوظائف. كإدارة الإجراءات وجدولة المعالج، وإدارة الذاكرة وإدارة الملفات . أي أن نواة النظام
تشكل كتلة كبيرة من البرمجيات المدمجة في طبقة واحدة . مماكان يزيد بشكل ملموس من
صعوبة عمليات الفحص والاختبار لصحة أداء هذه النواة وخلوها من أخطاء البرمجة . وتنفذ هذه
النواة في سوية النواة 8، وتحتاج الإجراءات من أجل العبور من مستوى البرمجيات إلى مستوى
النظام إلى استخدام استدعاءات النظام.
.MicroKernel مثال( 2): النواة المصغرة للنظام
نظرًا للصعوبة البالغة التي كان يمثلها تطوير نظام يونيكس بسبب ضخامة النواة واحتوائها على
عدد كبير من الوظائف في آن واحد، فقد ظهر في نهاية الثمانينات توجه نحو الاعتماد على
كأساس لتطوير نظم التشغيل المستقبلية. ويعتمد ،Micro Kernel مفهوم النواة المصغرة للنظام أو
التصميم الجديد على تقسيم النواة إلى سويتين :
نواة مصغرة : تحوي الأجزاء التي تحتاج إلى التعامل المباشر مع التجهيزات، كإدارة
الإجرائيات وجدولة المعالج، والسواقات البرمجية للتجهبزات . وهذه النواة المصغرة تعمل في
سوية النواة تمامًا مثل النواة السابقة لنظام يونيكس.
أخرجت العديد من وظائف النواة السابقة إلى مستوى التطبيقات: مثل نظام إدارة الملفات. هذه
الوظائف مبنية على شكل كتل تتصل بين بعضها البعض عن طريق تبادل الرسائل.
ويظهر الشكل التالي البنيان العام للأنظمة التي تعتمد النواة المصغرة :
التي تكون فيها تعليمات الدخل والخرج والتعامل مع بعض السجلات الحرجة :User Mode 7 حالة المستخدم
غير مسموحة.
وتكون فيها كافة التعليمات مسموحة ومستخدمة :Kernel Mode 8 حالة النواة
11
ملاحظة.
فإذا أرادت إجرائية ما قراءة معلومات من ملف، تقوم بإرسال طلب إلى إجرائية أخرى مسؤولة
ويقتصر دور .File server عن تنفيذ كافة الطلبات المتعلقة بالملفات وتعرف باسم مخدم الملفات
النواة في هذه الحالة على تمري ر الرسالة بين الإجرائي ة الطالبة، وتعرف أيضًا باسم إجرائية
وإجرائية المخدم. Client process الزبون
ويتكون النظام من عديد من إجرائيات المخدمات كمخدم الذاكرة ومخدم الشاشات ومخدم
الاتصال الشبكي، إلخ.
نتيجة لإخراج العديد من الوظائف خارج النواة، فإن هذا التصميم يتميز بالعديد من المزايا:
سهولة توسيع النواة: إذ أصبحت النواة الجديدة أصغر حجمًا وأكثر تخصصًا، مما يسهل
تطويرها إلى حد كبير.
من السهل استبدال الوظائف وترقيتها، مثل إضافة نوع جديد من الملفات إلى النظام، دون
الحاجة إلى إعادة توليد النواة واختبارها من جديد. لا بل من الممكن أن يتم ذلك دون الحاجة إلى
إيقاف النظام، إذ يكفي إيقاف إجرائية المخدم التي تحتاج إلى ترقية.
نتيجة لإخراج العديد من الوظائف خارج النواة، فإن هذا التصميم يتميز بالعديد من المزايا:
سهولة دعم تجهيزات جديدة: ولاسيما المعالجات، إذ أن الجزء الذي يتعامل مباشرة مع
التجهيزات بات محدودًا وواضحًا.
ازدادت الوثوقية إلى حد كبير: إذ أن حجم البرامج التي تعمل في مستوى النواة وتتعامل
مباشرة مع التجهيزات محدود جدًا بالمقارنة مع السابق. فإذا كان نظام الملفات يحتوي على خطأ
برمجي، فإن الخطأ لن يتنج عنه إلا توقف مخدم الملفات وليس توقف النظام بأكمله كما كان
يحدث سابقًا.
لقد لاقت هذه الفكرة ممانعة كبيرة في البداية بسبب التحدي الذي كان يمثله انخفاض الأداء الناتج
عن تقسيم النواة إلى عدة إجرائية والكلفة المتمثلة في توليد ونسخ الرسائل وزيادة عمليات التبديل
بين الإجرائيات.
ولكن النتائج الإيجابية كانت أكبر بما لايقاس من ذلك الانخفاض، و تعتمد أغلب أنظمة التشغيل
الحديثة بشكل أو بآخر على تصميم مشتق من مبدأ النواة المصغرة.
نهاية الوحدة
المحاضرة الثالثة:
1
الإجرائيات
1. تعريف
تعريف الإجرائية:
هي سلسلة من التعليمات التي تنفذ ضمن سياق تنفيذي معين يعرف باسم حالة الإجرائية.
تتضمن حالة الإجرائية عددًا من المعلومات مثل:
سجلات
مكدس
مساحة من الذاكرة مخصصة للإجرائية: متحولات عامة والذاكرة المخصص ديناميكيًا.
ويظهر الشكل التالي مساحة الذاكرة المخصصة للإجرائية :
ويمكننا أن نميز ضمن الشكل أربعة أجزاء للذاكرة المستخدمة:
يحوي التعليمات بلغة الآلة التي تقوم الإجرائية بتنفيذها :Text 1) الجزء الأول
مخصص لتخزين متحولات الإجرائية. وهو مقسوم بدوره إلى جزئين: :Data 2) الجزء الثاني
المتحولات الساكنة التي لايتغير حجمها: وعمر هذه المتحولات من عمر الإجرائية.
المتحولات الديناميكية: وهي متنوعة المنشأ وتخزن في موقعين مختلفين من الذاكرة:
0
MAX
Text
static data
heap
stack
Free
Memory
2
.Stack المكدس
في مكان خاص يعرف باسم المكدس Procedures تخزن المتحولات الخاصة بالإجراءات
ويتحرك بشكل متناقص، وعمر هذه المتحولات هو مساوٍ لعمر الإجراءات التي أنِشأتها . إذ بعد
انتهاء تنفيذ الإجراء يعود المكدس إلى وضعه قبل التنفيذ، وتختفي بالتالي المتحولات التي كانت
مخزنة عليه.
.Heap الكومة
المتحولات التي تحتاج إلى فترة تخزين تتجاوز عمر الإجرائي ة، مثل المؤشرات والأغراض،
والتي تتحرك بشكل متزايد. ،Heap فهي تخزن على الكومة
ولايجوز أثناء التنفيذ أن يتقاطع المكدس مع الكومة وإلا نتج عن ذلك تدمير للذاكرة وخطأ في
التنفيذ.
2. خصائص هامة للإجرائية
تعتبر الإجرائية واحدة التنفيذ : بمعنى أنه لايمكن أن تنفذ تع ليمتان من نفس الإجرائية بآن
واحد وإنما يجب أن تنفذا بالتتالي واحدة تلو الأخرى.
تعتبر الإجرائية واحدة تخصيص الموارد : أي أن نظام التشغيل يخصص الموارد المختلفة
كزمن المعالج والذاكرة والملفات للإجرائيات.
تكون الإجرائيات معزولة عن بعضها البعض : بحيث لايمكن لإجرا ئية أن تغير مباشرة من
حالة إجرائية أخرى، وبالتالي لايمكن لخطأ في برمجة تطبيق أن يؤثر على عمل تطبيقات
أخرى.
ونورد فيما يلي بعض الأمثلة عن إجرائيات مألوفة لدى العديد من المستخدمين:
الذي يقوم بقراءة وتنفيذ التعليمات التي يطلبها الم ستخدم Unix في نظام shell برنامج
بشكل تفاعلي.
عندما نطلب تنفيذ أي برنامج، يقوم نظام التشغيل عادة بإنشاء إجرائية وتكليفها بتنفيذ
البرنامج.
متصفح الوب هو إجرائية مستقلة.
3
3. حالات تنفيذ الإجرائية
تمر الإجرائية خلال فترة حياتها بعدة حالات للتنفيذ، ويتضمن مخطط الحالات الأبسط حالتي
تنفيذ:
أي أنها مستحوذة على وحدة المعالجة. :Running الإجرائية تعمل
ولكنها لاتعمل : أي أنها غير مستحوذة على وحدة Ready الإجرائية جاهزة للعمل
المعالجة.
ومن البديهي أنه في حالة نظام تشغيل يعمل على حاسوب وحيد المعالج، فستكون لدينا إجرائية
وعديد من ،Current Process واحدة على الأكثر تعمل، تدعى الإجرائية الحالية أو الراهنة
الإجرائيات التي لاتعمل . وتنتظر الإجرائيات التي لاتعمل دورها للحصول على المعالج مرتبة
في رتل انتظار، ويقوم نظام التشغيل بانتقاء الإجرائية التي تعمل من بين الإجرائيات في رتل
الانتظار.
ويظهر الشكل التالي مخطط الحالات مع التنقل بينها:
Ready
Dispatch
Running
Pause
Enter Exit
هذا المخطط مبسط إلى درجة مبالغ فيها، إذ يترك نقطة هامة جدًا بدون أية معالجة:
؟ ماذا تفعل الإجرائية عندما تتوقف مؤقتًا عن العمل منتظرة جصول حدث ما 1
إذ يفرض علينا هذا المخطط أن تبقى الإجرائي ة تستهلك وقت المعالج وتدور في حلقة مفرغة
حتى انتفاء سبب الانتظار . وهذا يعني أننا بكل بساطة نهدر أثمن موارد الحاسوب على
الإطلاق، وهو زمن وحدة المعالجة.
Cat–n testfile | more :UNIX لمزيد من التوضيح، نأخذ المثال التالي من نظام
يظهر المثال إجرائية أولى تقوم ب توليد أسطر مرقمة من
ملف، وترسل هذه الإجرائية خرجها إلى إجرائية ثانية
تقوم بعرض النتيجة مقطعة على الشاشة بحيث يمكن
تصفحها. من المؤكد أن الإجرائية الثانية لايمكنها أن
1 كقراءة عدد من المحارف؟
4
تقوم بشيء مالم تسلمها الإجرائية الأولى البيانات المطلوب عرضها . وفي انتظار هذه البيانات،
يجب أن توقف الإجرائية عن العمل وتوضع في حالة انتظار.
وتوضع الإجرائية في هذه الحالة ،waiting نقوم إذا بتعريف حالة جديدة، وهي حالة الانتظار
عند انتظارها لحدث ما . ويصبح مخطط الحالات على الشكل الجانبي (انقر عليه لتحصل على
النسخة المكبرة).
وباعتبار أنه لايجوز إعطا ء المعالج لإجرائية غير قادرة على الاستفادة منه، فإنه من المفيد ألا
نضع الإجرائيات التي هي في حالة الانتظار في نفس الرتل الخاص بالإجرائيات الجاهزة،
كمايظهر الشكل التالي:
Dispatch CPU
Ready Queue
Event Waiting Queue
occurs
Admit
Event wait
Timeout
وفي بعض أنظمة التشغيل ، يخصص عدد من أرتال الانتظار بحسب نوع الحدث الذي تنتظره
الإجرائية، وذلك بهدف تسريع عملية البحث.
إن كافة الإجرائيات تقوم بعدد كبير من عمليات الدخل والخرج خلال حياتها، وباعتبار أن الفرق
بين سرعة وحدة المعالجة وسرعة وحدات الدخل والخرج كبير جداً وهو في تزايد مطرد، فإن
أغلب الإجرائيات التي تعمل في نظام التشغيل تكون معلقة بانتظار انتهاء عمليات الدخل
والخرج.
5
من الممكن اللجوء نقل بعض هذه الإجرائيات خارج الذاكرة الرئيسية وتخزينها في ذاكرة
التخزين للحاسوب بهدف توفير الذاكرة الرئيسية لتتسع لعدد أكبر من الإجرائية ال جاهزة للعمل .
،suspended ونعرف إذا حالة جديدة هي حالة التعليق
وتنتج عن نقل إجرائية في حالة الإنتظار بعيدًا عن
الذاكرة المركزية.
يجب التمييز بين الإجرائيات المعلقة وتلك التي تكون
في حالة تعليق وينتفي سبب انتظارها، وصلت
المحارف التي كانت تنتظرها مث ً لا، ونحتاج لذلك إلى حالتين جديتين في مخطط الحالات . في
هذه الحالة يجب إعادة الإجرائية إلى الذاكرة المركزية ولكن قد لايتاح ذلك فورًا، ولهذا نحتاج
وذلك موضح في الشكل .suspended-ready و Suspended-waiting : إلى التمييز بين الحالتين
الجانبي.
4. الأنظمة متعددة الإجرائيات
في بداية عمر أنظمة التشغيل، لم يكن بإمكان هذه الأنظمة تنفيذ أكثر من إجرائية واحدة، وأحد
ومشكلة هذه الأنظمة هي في كونها قاصرة عن تلبية متطلبات .DOS أهم الأمثلة عليها هو نظام
المستخدم الذي يحتاج إلى تنفيذ أكثر من عمل في آن واحد (مثال: تحميل ملف على موقع
إنترنت بينما يقوم المستخدم بتحرير نص).
DOS واعتمدت هذه الأنطمة على آليات معقدة بعض الشيء لتلبية هذه المتطلبات، مثل نظام
وهي برمجيات ،TSR: Terminate And Stay Resident الذي كان يستخدم برمجيات من نوع
تبقى دومًا في الذاكرة الرئيسية بعد انتهائها من التنفيذ، ويستدعي ها نظام التشغيل بشكل غير
متزامن. ولكنها ظلت تعاني من مشكلات عديدة كانعدام العزل بينها . إذ كان بإمكان البرنامج أن
يكتب عن طريق الخطأ في الذاكرة المخصصة لبرنامج آخر، مما كان يتنج عنه العديد من
6
الأعطال غير المقبولة.
كافة أنظمة التشغيل الحالية هي من النوع المت عدد الإجرائيات، أي بإمكانها تنفيذ أكثر من إجرائية
وهناك أشكال مختلفة للأنظمة .Windows ونظام Unix واحدة، وأهم هذه الأمثلة هو نظام
متعددة الإجرائيات سنراها لاحقًا وهي غالبًا ما تكون مصممة بحيث تلائم حاجات شريحة معينة
من التطبيقات أو المستخدمين (مثل أنظمة الزمن الحقيقي أو أنظمة تقاسم الوقت).
إحدى أهم المشكلات التي تعاني منها الأنظمة متعددة الإجرائيات هي مشكلة تقاسم الموارد
وتنظيم طلبات الإجرائيات للموارد وحجزها . إذ يبقي سؤال اختيار الإجرائية التي يحق لها
استخدام موارد الحاسوب مطروحًا باستمرار، وأهم تلك الموار د على الإطلاق هو زمن المعالج .
والحل التقليدي هو آلية تعدد الإجرائيات التبديلي، إذ يقوم نظام التشغيل بإعطاء المعالج لإجرائية
ما ولفترة معينة يقوم بعدها بسحب المعالج من هذه الإجرائية وإعطائه لإجرائية أخرى.
نتكلم هنا عن الحالة التقليدية، وهي حالة الحاسوب وحيد المعالج، حيث يعرف تنفيذ عدة
وذلك للتمييز بينه وبين التنفيذ في بيئة متعددة ،concurrency إجرائيات في آن واحد بالتوارد
.parallel المعالجات حيث يكون التنفيذ تفرعيًا
ويطرح تحقيق التوارد العديد من الأسئلة التي تحتاج إلى إجابة:
ما هو معيار اختيار الإجرائية التي ستحصل على المعالج
ما هو السبب الذي يطلب من أجله نظام التشغيل من الإجرائية التي تعمل التخلي عن
المعالج
كيف سيتم حفظ واسترجاع حالة الإجرائية عند تبديل المعالج بين الإجرائيات
ماهي الاحتياطات المتخذة لضمان العدل بين الإجرائيات في توزيع زمن المعالج
تعريفات أساسية
تعتمد أنظمة التشغيل في معظم أعمالها على الاستجابة للأحداث، إذ تنتظر وقوع حدث، ومن ثم
تعالج الحدث لدى حصوله، لتعود بعدها إلى اتنظار حدث جديد . وتعتمد في ذلك على التبديل بين
الإجرائيات المختلفة التي تقوم كل منها بمهمة محددة، ونورد فيمايلي بعض الأمثلة على الأحداث
التي تؤدي إلى حصول تبديل بين الإجرائيات:
عندما يضغط المستخدم على أحد أزرار لوحة المفاتيح، يظهر الحرف المطلوب على
الشاشة.
تطلب إحدى الإجرائيات فتح أحد الملفات وذلك عبر استدعاء إحدى خدمات نظام
التشغيل. فيقوم النظام بالبحث عن أجزاء القرص الصلب التي يج ب نسخها ضمن
7
الذاكرة الرئيسية، ويرسل الأمر اللازم إلى وحدة التحكم بالقرص الصلب للقيام بذلك.
عند انتهاء وحدة التحكم بالقرص الصلب من قراءة الأجزاء المطلوبة تقوم بتوليد
للمعالج . ويقوم نظام التشغيل أثناء معالجته للمقاطعة بتسليم Interrupt مقاطعة
المعطيات المقروءة للإجرائية التي طلبتها ويطلب منها متابعة العمل.
يطلب متصفح الإنترنت إحضار صفحة، وبناء عليه يقوم نظام التشغيل بتوليد الرزم
الواجب إرسالها عبر الشبكة إلى المخدم المطلوب، ومن ثم يقوم بإرسالها، وتتوقف
.(waiting الإجرائية عن العمل منتظرة الجوات (حالة
يرد جواب من مخدم الوب على شكل رزم تحتوي المعلومات المطلوبة، وينتج عن
ذلك مقاطعة للمعالج . ويقوم نظام التشغيل بمعالجة المقاطعة لتحديد الإجرائية التي
يجب أن تستلم الرزم ويقوم بتوجيهها إليها.
عند انتهاء الحصة الزمنية للإجرائية، يجب على نظام التشغيل أن يقوم بحفظ حالة
الإجرائية التي تمتلك المعالج، واختيار إجرائية أخرى ليقوم بتسليمها المعالج
واسترجاع حالتها المحفوظة سابقًا وشحنها ضمن المعالج.
يمكننا هنا التعرف على عمليتين أساسيتين نقوم بتعريفهما فيما يلي:
تسمى عملية انتخاب الإجرائية التي يتم تخصيصها بالمعالج :scheduling الجدولة
وهي عملية فائقة الأهمية وسنفرد لها فص ً لا خاصًا. ،scheduling بالجدولة
تسمى مجموعة المعلومات التي يستخدمها نظام :Process context سياق الاجرائية
وتسمى عملية حفظ .Process context التشغيل لتحديد حالة الإجرائية بسياق الاجرائية
حالة الإجرائية التي تمتلك المعالج واسترجاع حالة الإجرائية التي ستحل محلها بتبديل
ويعتبر تبديل السياق أحد أهم العمليات التي يقوم بها نظام .context switching السياق
التشغيل، لاسيما وأنها تتكرر بتواتر كبير جدًا.
سؤال: كيف يحقق نظام التشغيل عملية تبديل السياق ؟ لاسيما إذا أخذنا بعين الاعت بار أن
المعالجات تمتلك عددًا محدودًا من الموارد . فعلى سبيل المثال، يمتلك المعالج مجموعة واحدة
من السجلات، بينما تمتلك كل إجرائية مجموعة خاصة بها من قيم السجلات.
الحل: استخدام مساحة محددة من الذاكرة لحفظ واسترجاع كل المعلومات التي تمثل حالة المعالج
.Process control block لحظة تبديل السياق. وتعرف هذه المساحة بكتلة التحكم بالإجرائية
البنى المستخدمة في إدارة الإجرائيات
كتلة التحكم بالإجرائية
تنشأ كتلة التحكم بالإجرائية لدى إنشاء الإجرائية، وهي أحد أهم بنى المعطيات الموجودة في
8
نظام التشغيل، إذ تستخدم في أغلب ا لوظائف الموجودة ضمن
النظام، كالجدولة، وتخصيص الموارد ومراقبة الأداء.
ماذا يوجد ضمن كتلة التحكم بالإجرائية؟
يتوقف هذا عادة على البنيان الحاسوبي الذي يتعامل معه نظام
التشغيل، ولكن هناك معلومات من المؤكد أنها ستخزن دومًا
ضمن كتلة التحكم بالإجرائية وهي مبينة في الشكل الجانبي.
معلومات التحكم بالإجرائية : مثل حالة تنفيذ الإجرائية،
والشريحة الزمنية المتبقية لها، وأولويتها في حال كان نظام التشغيل يدعم الأولويات.
هوية أو رقم الإجرائية وهوية المستخدم مالك الإجرائية : إذا كان النظام يدعم تعدد
المستخدمين.
Processor Status Word حالة الإجرائية: وهي تتضمن سجلات المعالج وكلمة حالة المعالج
ومعلومات أخرى.
معلومات خاصة بإدارة الذاكرة المخصصة للإجرائية، لاسيما جداول الربط بين الذاكرة
الرئيسية والذاكرة الافتراضية المخزنة على القرص الصلب.
قائمة بالموارد المحجوزة لصالح الإجرائية: كالملفات المفتوحة وبوابات الدخل والخرج.
كتلة التحكم بالإجرائية: ونورد فيما يلي توصيفًا مفص ً لا لبعض هذه الحقول:
معلومات الهوية:
هوية الإجرائية : وهي عادة ماتكون رقمًا صحيحًا فريدًا، ويستخدم هذا الرقم كفهرس
لجدول الإجرائيات.
هوية الإجرائية الأم : وهي معلومة هامة إذ تسمح بتحديد
تبعية الإجرائيات وتمرير نتائج تنفيذ الإجرائية إلى
الإجرائية التي أنشأتها، وهي معلومة هامة جدًا في العديد
.Unix في نظام shell من التطبيقات مثل مفسر الأوامر
معلومات الهوية:
هوية المستخدم صاحب الإجرائية : وهي معلومة هامة
جدًا في الأنظمة م تعددة المستخدمين التي نحتاج فيها إلى حماية المعلومات الخاصة بكل
مستخدم من باقي المستخدمين . إذ تعتمد آلية الحماية على تعريف حقوق استخدام لكل ملف
ولكل مجموعة من المستخدمين وتكون بمثابة قفل، وتكون هوية صاحب الإجرائية بمثابة
المفتاح الذي يقارن مع القفل الموضوع على الملف لدى محاولة فتح الملف.
:CPU state حالة وحدة المعالجة
Process state
Program counter
Registers
Memory limits
List of open files
…...
Process state
Program counter
Registers
Memory limits
List of open files
…...
9
تمثل صورة عن الإجرائية في لحظة ما، وهي تتضمن قيم سجلات المعالج بالإضافة إلى كلمة
المعرفة في EFLAGS ومثال عليها مجموعة السجلات ،Processor Status Word حالة المعالج
والتي تستخدمها كافة أنظمة التشغيل التي تعمل على هذا المعالج. Pentium معالجات
حالة تنفيذ الإجرائية: وهي يمكن أن تأخذ قيمًا عديدة كما سبق وشرحنا.
الموارد التي تحجزها الإجرائية : مثل: ملفات، تجهيزات دخل وخرج، إلخ ...، وهذه المعلومة
هامة جدًا لأن نظام التشغيل قد يضطر إلى تحرير الموارد ف ي حال أنهت الإجرائية عملها دون
تحريرها، مثل إغلاق الملفات المتروكة مفتوحة.
معلومات أخرى:
أولوية الإجرائية: لاسيما إذا كان نظام التشغيل يعمل بالزمن الحقيقي
معلومات المحاسبة: كزمن المعالج المستهلك، الزمن المتاح، إلخ.
حالة الدخل والخرج : بمافيها طلبات الدخل والخرج المعلقة، والتجهيزات المحجوزة،
وقائمة الملفات المفتوحة.
Resource Descriptors موصفات الموارد
غالبًا ما تكون الموارد الحاسوبية قابلة لإعادة الاستخدام، وغير متاحة بكثرة . وتحتاج الإجرائيات
إلى حجزها قبل استخدامها ومن ثم تحريرها لدى نهاية الاستخدام . ومن الممكن أن تكون هذه
الموارد عتادية كالبوابات التسلسلية أو برمجية كبعض البرمجيات المدفوعة والتي لايمكن
استخدامها في آن واحد من قبل عدد من المستخدمين يتجاوزعدد الرخص المباعة . ويحتاج نظام
التشغيل عادة إلى العديد من المعلومات الخاصة بالموارد، مثل:
صف الموارد ونوعها
قائمة بعدد ومعرفات الوحدات المتاحة من المورد المعني
قائمة الإجرائيات المنتظرة للمورد والتي لايمكن تلبية طلباتها
العمليات الأساسية للإجرائيات
:Create إنشاء إجرائية جديدة باستخدام
1) تخصيص معرف جديد وفريد للإجرائية، وغالبًا ما يستخدم عداد لهذا الغرض.
2) حجز الذاكرة اللازمة لكافة أجزاء الإجرائية، بمافيها مساحة الذاكرة اللازمة لتخزين
متحولات البرنامج والمكدس . ويمكن أن تنسخ الإجرائية قيم مساحة الذاكرة من الإجرائية
الأم. بالإضافة إلى حجز الذاكرة اللازمة لكتلة التحكم بالإجرائية.
3) إنشاء كتلة تحكم بالإجرائية جديدة خاصة بالمعرف المذكور أعلاه وإضافتها إلى جدول
10
الإجرائيات في النظام . وتأسيس القيم المختلفة في هذه الكتلة مثل معرف الإجرائية الأم، وقائمة
الإجرائيات الأبناء التي تكون في البداية فارغة، وسجل عداد تنفيذ البرنامج الذي تكون قيمته
البدائية هي عنوان بداية تنفيذ البرنامج، ومؤشر المكدس المستخدم في نظام التشغيل.
:Create إنشاء إجرائية جديدة باستخدام
Ready 4) الحالة الأساسية للإجرائية، والتي غالبًا ماتكون
5) إضافة الإجرائية الجديدة إلى قائمة أبناء الإجرائية الأم
6) تخصيص الموارد اللازمة في البداية
7) تعريف الأولوية البدائية للإجرائية
8) إضافة الإجرائية إلى قائمة الإجرائيات الجاهزة للعمل
Suspend تعليق عمل الإجرائية
1) لايمكن للإجرائية أن تعلق إجرائيات أخرى غير أبنائها
2) في حال كون الإجرائية المعلقة حاصلة على المعالج، توقف عن العمل وتحفظ حالة
المعالج ضمن كتلة التحكم بالإجرائية
3) سحب الإجرائية من قائمة الإجرائيات الجاهزة للعمل ووضعها ضمن قائمة الإجرائيات
المعلقة.
Activate تنشيط الإجرائية
1) تغيير حالة الإجرائية من معلقة إلى جاهزة
2) سحب الإجرائية من قائمة الإجرائيات المعلقة للعمل ووضعها ضمن قائمة الإجرائيات
الجاهزة.
Destroy إنهاء الإجرائية
1) يمكن أن يكون الإنهاء متسلس ً لا، أي ينهى عمل الإجرائية وكافة ابنائها.
2) إذا كانت الإجرائية تعمل (حاصلة على المعالج) يوقف عملها
3) تحرير كافة الموارد المخصصة للإجرائية
4) حذف كتلة التحكم بالإجرائية المخصصة للإجرائية المنهاة.
Change Priority تغيير الأولوية
1) تغير قيمة الأولوية المحفوظة ضمن كتلة التحكم بالإجرائية
2) تغيير موقع الإجرائية في خط الانتطار أو وضعها في خط انتظار جديد لتعكس الأولوية
11
القديمة.
Threads 5. النياسب
سبق ورأينا أن للإجرائية دوران مهمان بالنسبة لنظام التشغيل:
واحدة التنفيذ : أي أن الإجرائية تقوم بتنفيذ سلسلة متتالية من التعليمات التي لايمكن أن
تتداخل مع بعضها البعض.
واحدة تخصيص الموارد : إذ يقوم نظام التشغيل بتخصيص الإجرائية بفضاء العنونة
ومساحة الذاكرة اللازمة لشحن صورة الإجرائية: التعليمات + المعطيات.
هذان الدوران هما في الحقيقة مستقلان كليًا عن بعضهما البعض . ولئن كان مصممو نظم
التشغيل في المراحل الأولى قد دمجوا بينهما دون أن يروا في ذلك مشكلة، فإن التطور الذي
حصل على استخدامات الحاسوب والتغير في طبيعة التطبيقات والتوجه نحو التطبيقات المتعددة
الإجرائيات قد فرض الفصل بينهما في لحظة ما.
ظهر مفهوم النيسب في نهاية الثمانينات، وكان يهدف بشكل أساسي إلى حل مشكلة بطء تبديل
السياق التي تعاني منها الإجرائية نظرًا لضخامة السياق المخصص لها . بالإضافة إلى مشكلة
صعوبة التخاطب بين الإجرائيات بسبب عزل فضاءات العنونة عن بعضها البعض . وكان الحل
هو الفصل بين مفهومي ا لتنفيذ وتخصيص الموارد، بحيث
تبقى الإجرائية هي واحدة تخصيص الموارد، وتعرف
واحدة جديدة للتنفيذ هي النيسب.
يمكن أن تحوي الإجرائية عدة نياسب تشترك كلها في
الموارد المخصصة للإجرائية . لكل نيسب سياق تنفيذ
خاص به مكون من مجموعة سجلات المعالج وعداد
البرنامج ومكدس . أما سياق الإجرائية فهو سياق الموارد،
كصورة الإجرائية في الذاكرة وا لملفات المفتوحة لصالح
. الإجرائية 2
يظهر الشكل التالي الفرق بين النموذج القديم للإجرائية
التي تحوي نيسبًا واحدًا، ونموذج الإجرائية المتعددة
النياسب. ونلاحظ أن الرسم يظهر بوضوح وجود سياق
2 أي أن نظام التشغيل لا يعرف أي نيسب في الإجرائية طلب فتح الملف.
12
خاص بكل نيسب، وسياق آخر مشترك بين كل نياسب الإجرائية.
انقر على الشكل المجاور لترى النسخة المكبرة.
مزايا استخدام النياسب
يصل فرق الزمن بين Solaris اختصار الزمن اللازم لإنشاء وإنهاء واحدة تنفيذ، ففي نظام
إنشاء إجرائية وإنشاء نيسب إلى 30 ضعفًا.
اختصار الزمن اللاز م لتبديل السياق بين وحدات التنفيذ، إذ أن سياق التنفيذ صغير
بالمقارنة مع سياق الموارد . ولانحتاج إلى تبديل سياق الموارد إلا عندما نقوم بتبديل
يصل الفرق إلى 5 Solaris السياق بين نيسبين من إجرائيتين مختلفتين، وفي نظام
أضعاف.
تسهيل عملية التخاطب بين وحدات التنف يذ إلى حد كبير . إذ أصبحت المتحولات الخاصة
بالإجرائية مشتركة بين كل النياسب، بينما كان من الصعب جدًا استخدام متحولات
مشتركة بين الإجرائيات . وكانت عمليات الاتصال بين الإجرائيات بطيئة جدًا لأنها تمر
عبر استدعاء نواة نظام التشغيل.
تتلاءم النياسب العديد من التط بيقات الحديثة، ولاسيما الواجهات التخاطبية للمستخدمين .
فأغلب البرمجيات تحوي على الأقل نيسبين، يقوم الأول بتحديث الواجهة التخاطبية، بينما
يقوم الثاني بتنفيذ العمليات المطلوبة . ومن أبسط الأمثلة : التصحيح التلقائي لملف نصي
أثناء القيام بنسخ ملف. Progress bar بينما يقوم المستخدم بالكتابة، وتحديث دليل التقدم
مستوى تحقيق النياسب
يختلف مستوى الدعم للنياسب بين نظام تشغيل وآخر، فمن الممكن أن تكون النياسب على
وفي هذه الحالة لاترى النواة إلا الإجرائية، ويكون تعريف ،user threads مستوى المستخدم
النياسب وإدارة تقاسم الزمن بينها من مسؤولية مكتبات تعمل على مستوى المستخدم . وتدعم
أغلب أنظمة التشغيل الحديثة، بما فيها لينوكس وويندوز إكس -بي، وماك أوإس، وسولاريس،
أي أن التحكم بالنياسب يتم من قبل النواة. .kernel threads نياسب معرفة على مستوى النواة
سنبين في هذا المقطع العلاقة التي يمكن أن تكون بين نياسب المستخدم ونياسب النواة.
13
عديد لواحد : ويخصص في هذه الحالة نيسب واحد من
النواة مقابل عدة نياسب من مستوى المستخدم . وتتم
إدارة النياسب ضمن مكتبة تعمل على مستوى
المستخدم، وهذا الحل يوفر كثيرًا في موارد الحاسوب
إذ يختصر عدد النياسب اللا زمة. ولكن له سيئة هامة،
وهي أنه يوقف كل النياسب عن العمل إذ قامت إحداهن
بتنفيذ عملية تؤدي إلى التوقف، كما لايمكن لهذا النوع
من الأنظمة أن يستفيد من تعدد المعالجات . ومثال عليها
.GNU Portable Threads هو مكتبة
واحد لواحد : في هذه الحالة ينشأ نيسب من النواة
مقابل كل نيسب من مستوى المستخدم، ومن ميزات
هذا الحل أنه يزيد من درجة التوارد للنظام إذ
لايعاني من عيوب الحالة السابقة . ولكنه بالمقابل قد
يكون مكلفًا، إذ قد يؤدي إنشاء عدد كبير من
النياسب إلى الحد من أداء التطبيقات، لاسيما أن
الزمن اللازم لإنشاء نياسب النواة أكبر بكثير من
نياسب المستخدم . وتلجأ الأنظمة التي تدعم هذا الحل
(لينوكس، وأنظمة ويندوز المختلفة ) إلى فرض حد
لعدد نياسب النواة التي يمكن إنشاؤها.
14
عديد لعديد : وهو حل وسط بين الحلين
السابقين، إذ يسمح بتخصيص عدد من
نياسب النواة أقل أو يساوي عدد نياسب
مستوى ال مستخدم. ويكون عدد نياسب
النواة متناسبًا عادة مع إمكانات الحاسوب
المستخدم، وبذلك نتلافي المشكلات التي
يعاني منها كلا الحلين . وهو مستخدم في
HP- مثل Unix العديد من مشتقات نظام
.UX, Tru64
مكتبات النياسب
تستخدم مكتبات النياسب كواجهة برمجية تسمح لمطوري التطبيق ات باستخدام النياسب في
تطبيقاتهم، وهناك نوعان من المكتبات:
مكتبات تعمل كليًا في مستوى المستخدم بدون أي دعم من النواة: وهي تعتمد على
النموذج عديد لواحد. وتنفذ كافة الأوامر المتعلقة بالنياسب على مستوى المستخدم ولاتعتمد
البتة على استدعاءات النظام.
مكتبات تعمل في مستوى النواة: وفي هذه الحالة تكون هناك استدعاءات للنظام تدعم
النياسب.
ومكتبة ،Win ومكتبة 32 ،POSIX Pthreads هناك حاليًا ثلاث مكتبات هي الأكثر انتشارًا: مكتبة
.Java
نظام التشغيل وخصوصية النياسب
أدى إدخال النياسب كجزء أساسي من نظام التشغيل إلى طرح العديد من التعديلات على
استدعاءات النظام المتعلقة بالتنفيذ، والتي سنوردها هنا تباعًا.
:exec و fork() الاستدعاءات
ينشئ إجرائية جديدة تنفذ عوضًا exec يقوم بنسخ الإجرائية الطالبة، والاستدعاء fork الاستدعاء
عن الإجرائية الطالبة.
15
بنس خ كافة النياسب الموجودة ضمن الإجرائية، أم أنها fork السؤال المطروح هنا : هل تقوم
تكتفي بنسخ النيسب الطالب؟
:exec و fork() الاستدعاءات
الحالة الأولى تقوم .fork لقد اعتمدت بعض أنظمة التشغيل ح ً لا يعتمد على وجود حالتين لاستدعاء
إذ ،exec بنسخ النيسب الطالب فقط، وعلى المبرمج استخدامها عندما يليها مباشر ة استدعاء ل
سيقوم هذا الاستدعاء بإنهاء الإجرائية المنشأة بكافة نياسبها، فلاداعي إذًا لنسخ كافة النياسب .
والحالة الثانية تقوم بنسخ كافة النياسب، وتستخدم عندما لايكون هناك إنهاء مباشر للإجرائية،
وبالتالي يجب أن تكون الإجرائية الجديدة مطابقة تمامًا للإجرائية السابقة.
:Cancellation إلغاء النيسب
الإلغاء هو الإنهاء القسري للنيسب قبل
انتهائه من عمله بشكل طبيعي.
فعلى سبيل المثال، إذا كانت هناك عدة
نياسب تعمل على التوازي لإجراء بحث
ضمن شجرة بيانات، ووصلت إحداها إلى
النتيجة، فلاداعي لمتابعة عمل الأخريات.
هناك حالتان للإلغاء: :Cancellation إلغاء النيسب
فإما أن يكون الإلغاء غير مت زامن بالمرة , ويوقف النيسب فورً ا: وهذا الوضع يطرح
مشكلة الموارد التي قام النيسب بطلبها، إذ أن نظام التشغيل لن يكون قادرًا على استرجاعها
تلقائيها بسبب كونها محجوزة لصالح الإجرائي ة ككل وليس للنيسب
مثل فتح ملف.
أو يكون الإلغاء مؤج ً لا: بحيث يكون بإمكان النيسب أن يتحقق من وجود طلب لإلغائه، وفي
هذه الحالة يقوم بتحرير الموارد التي قام بحجزها قبل إنهاء عمله . ويحتاج هذا النوع من الإلغاء
إلى تعاون المبرمج بالإضافة إلى وجود آليات تسمح بإعلا م النيسب بأن عليه التوقف . ومثال
.Pthreads الموجودة في مكتبة Cancellation points عليها هي نقاط الإلغاء
:Signal handling معالجة الإشارات
لإعلام الإجرائية بحصول حدث ما UNIX الإشارة هي أحد الأدوات المستخدمة في نظام التشغيل
16
مثل القسمة على صفر، أو حدوث خطأ في العنونة. وتتبع الإشارات عادة المنهجية التالية:
1) تولد الإشارة عند حصول حدث ما.
2) يتم تسليم الإشارة إلى الإجرائية.
3) عند وصول الإشارة إلى الإجرائية يجب معالجة هذه الإشارة.
:Signal handling معالجة الإشارات
والمشكلة في الأنظمة المتعدد النياسب هي في تحديد النيسب ال مسؤول عن معالجة الإشارة ضمن
الإجرائية. وتوجد هناك عدة مقترحات بهذا الخصوص:
1) تسليم الإشارة للنيسب المعني بهذه الإشارة.
2) تسليم الإشارة لكل نيسب من نياسب الإجرائية.
3) تسليم الإشارة إلى عدد من نياسب الإجرائية.
4) تحديد نيسب معين لاستلام كل إشارات الإجرائية.
من مبدأ السماح للنيسب بتحديد الإشارات التي يقبلها UNIX وينطلق الحل الأكثر شيوعًا في نظام
والإشارات التي يرفضها، وتسليم الإشارة لأول نيسب يقبلها.
مجموعات النياسب:
يعتبر مخدم الوب أحد أشهر التطبيقات التي تستفيد استفادة كبير من وجود النياسب . وفي الوضع
التقليدي، ينشئ المخدم نيسبًا لمعالجة كل طلب وارد، وهذا أسرع بكثير من إنشاء إجرائية، ولكنه
يمثل رغم ذلك تأخيرًا عن معالجة تنفيذ الطلب، بالإضافة إلى إنهاء عمل النيسب بعد تخديم الطلب
الوارد. وتلجأ العديد من التطبيقات إلى إنشاء عدد كبير من النياسب الجاهزة والقابلة لإعادة
الاستخدام، والتي تنتظر تكليفها بتخديم طلب ثم تعود إلى وضع الانتظار بعد انتهائها من ذلك .
وهذا الحل يمتلك العديد من المزايا، أهمها توفير الزمن اللازم لإنشاء وإنهاء النيسب، بَالإضافة
إلى القدرة على تحديد عد الطلبات التي يمكن تخديمها بآن واحد لئلا يحصل تدهور في أداء المخدم
إذا ما ترك عدد النياسب المستخدمة مفتوحًا.
وجود معطيات خاصة بالنيسب:
فقد عرفنا النياسب كواحدات للتنفيذ تشترك بين بعضها البعض في المعطيات الخاصة بالإجرائية
الأم. ولكن في بعض الحالات هناك حاجة لتخصيص بعض المعطيات لنيسب بعينه، ومثال على
وتكليف كل نيسب بمعالجة مناقلة transactions ذلك استخدا م النياسب في معالجة المناقلات
مستقلة. وتدعم أغلب مكتبات النياسب إمكانية تعريف معطيات خاصة بالنيسب.
17
التخاطب مع المجدول:
هناك العديد من الحالات التي يكون من الضروري فيها تعريف آليات للاتصال بين التطبيقات
والنواة ولا سيما في حالة نموذج عديد لعديد الذي يربط عدة نياسب من مستوى المستخدم مع عدد
من نياسب النواة. والهدف هو الاستفادة إلى الحد الأقصى من إمكانية التوارد المتاحة للتطبيق.
يتعامل نظام التشغيل مع نياسب النواة على أنها معالجات افتراضية يقوم بتخصيصها
للإجرائيات، وال تي تقوم بدورها بتوزيع النياسب من مستوى المستخدم عليها . وقد تحتاج
الإجرائية إلى أكثر من معالج افتراضي لتحسين أدائها، لاسيما إذا كانت نسبة عمليات الدخل
والخرج فيها مرتفعة.
تتخاطب النواة مع التطبيق لإدارة توزيع هذه المعالجات الافتراضية على الشكل التالي:
1) يزود نظام التشغيل التطبيق بعدة معالجات افتراضية، ويقوم التطبيق بجدولة نياسبه عليها
ويسلم هذا ،upcall 2) تعلم النواة التطبيق عن أحداث معينة باستخدام استدعاء صاعد
الاستدعاء إلى إجراء خاص بمكتبة النياسب لإعلامها بالحدث. ويجب أن يعمل الإجراء
الخاص على معالج افتراضي مخصص له.
تتخاطب النواة مع التطبيق لإدارة توزيع هذه المعالجات الافتراضية على الشكل التالي:
3) فإذا كان الحدث متعلقًا بتعليق عمل المعالج الإفتراضي بسبب طلب أحد النياسب لعملية
دخل/خرج مث ً لا، تعلم النواة الإجرائية بأن هناك نيسبًا سيتوقف وتزوده بهوية النيسب،
وتخصص الإجرائية بمعالج افتراضي جديد.
4) يقوم معالج الاستدعاء باستلام المعالج الافتراضي الجديد ويحفظ حالة النياسب التي
ستتوقف عن العمل ويحرر المعالج الافتراضي الذي كانت تستخدمه. كما يقوم بتخصيص
المعالج الجديد لنياسب قادرة على العمل.
تتخاطب النواة مع التطبيق لإدارة توزيع هذه المعالجات الافتراضية على الشكل التالي:
5) عند ورود الحدث الذي تسبب بتعليق عمل المعالج الافتراضي، تبلغ النواة الإدرائية
بورود الحدث، وتحتاج الإجرائية إلى معالج افتراضي لتنفيذ معالج الاستدعاء.
6) تخصص النواة الإجرائية بمعالج افتراضي جديد، أو تطلب سحب أحد المعالجات
الافتراضية التي تستخدمها الإجرائية. يقوم معالج الاستدعاء بإعادة النيسب المعلق إلى قائمة
النياسب الجاهزة للعمل، وبعد انتهائه يخصص المعالج الافتراضي لإحدى النياسب الجاهزة.
18
6. خلاصة
رأينا في هذا الفصل مفاهيم التنفيذ التي يعتمدها نظام التشغيل، وعرف نا الإجرائية كواحدة التنفيذ
وتخصيص الموارد، واستعرضنا حالات التنفيذ المختلفة التي يمكن أن تمر فيها الإجرائية،
بالإضافة إلى البنى المستخدمة لتمثيل الإجرائيات والموارد والعمليات التي يتيحها نظام التشغيل
للتعامل مع الإجرائيات . عرضنا أيضًا الأسباب التي أدت إلى الإبقاء على الإجرائيات كواحدة
لتخصيص الموارد فقط، بينما عرف النيسب كواحدة للتنفيذ . وفي النموذج الجديد، تحتوى
الإجرائية على عدة نياسب تتقاسم الموارد التي تملكها الإجرائية . كما طرحت العديد من النقاط
التي نتجت عن ظهور النياسب والتي لم تكن مطروحة سابقًا.
نهاية الوحدة
المحاضرة الرابعة:
1
التزامن بين الإجرائيات
1. مقدمة
عادة للدلالة على إيجاد علاقة زمنية بين الأحداث. Synchronization يستخدم مصطلح التزامن
مثال: تتم معالجة البيانات بعد الانتهاء من قراءتها.
تعرف هذه الجملة البسيطة حدثين:
قراءة البيانات
معالجة البيانات
وربما كان هذا المثال ب سيطًا وبديهيًا، ولكنه يعبر في آن واحد عن ضوابط للتزامن لايجوز
المساس بها لأنها في صلب تصميم نظام التشغيل . فمن المتعارف عليه في أغلب أنظمة التشغيل
هي عملية متزامنة، أي أن Read أن عملية قراءة البيانات التي تتم باستخدام استدعاء النظام
الاستدعاء لاينتهي ولايعيد نتيجة قبل الانتهاء من قراءة البيانات المطلوبة.
وفي حال وجود عمليات غير متزامنة، فإن العلاقة المذكورة أعلاه لاتعود صحيحة البتة، إذ
سينتهي الاستدعاء دون قراءة كامل البيانات، وسيجد مبرمج التطبيق نفسه مضطرًا لاختبار
صحة البيانات وحجم البيانات كلما طلب استخدامها.
A يمكننا أيضًا تعريف ضوابط للتزامن أكثر تعقيدًا من المثال أعلاه : لايجوز حصول الحدث
في آن واحد، ويعرف هذا النوع من الضوابط باسم "الاستبعاد المتبادل " B والحدث
.Mutual Exclusion
يبدو تحقيق هذه الضوابط سه ً لا جدًا للوهلة الأولى، لا سيما في ضوء التنفيذ ا لتسلسلي للتعليمات
ضمن الإجرائية . ولكن سرعان ما يتبدد هذا الانطباع عندما نأخذ بعين الاعتبار أن نظام التشغيل
يقوم بالتبديل بين الإجرائيات بحيث لايمكن ضمان أي علاقة ترتيب أو تزامن بين تعليمات
إجرائيتين مختلفتين.
يتسم عمل الإجرائيات بأنه غير متزامن أساسًا، ويم كن تشبيهه بشخصين يعملان في مكانين
مختلفين وكل منهما لديه ساعة يستخدمها لترتيب الأعمال التي يقوم بها، ولكن بدون أن يكون
هناك تنسيق بين الساعتين.
ولاتوجد عادة مشكلة في ذلك طالما لايوجد هناك رابط مشترك بين هذه الإجرائيات، ولكن يمكن
أن يكون هناك العديد من الروابط التي تفرض علينا مزامنة هذه الإجرائيات.
بالإضافة إلى علاقة زمنية بين الحدثين :
قراءة البيانات تسبق معالجتها.
2
2. مشكلات التنفيذ المتوارد
( المتحولات المشتركة: مثال( 1
إن أحد أهم وأبسط الأسباب التي تفرض مزامنة الإجرائيات هي قيامها بتعديل متحولات
مشتركة. ودعونا نعرض مثا ً لا على ذلك:
ملاحظة.
ملاحظة هامة : نذكر بأن ترتيب تنفيذ التعليمات ضمن الإجرائية الواحدة هو تسلسلي، وأن هناك
.A1 B2 B علاقة ترتيب كلي بين هذه التعليمات. أي أنه من الخطأ إيراد احتمال التنفيذ 1
3
( المتحولات المشتركة: مثال( 2
المتحولات المشتركة: ذرية التعليمة
يمكن تحقيق ذرية التعليمة بالاعتماد على المعرفة الض منية بآلية عمل نظام التشغيل، إذا حجبنا
كافة المقاطعات أثناء تنفيذ هذه التعليمة . فالتبديل بين إج رائية وأخرى ينتج عن حدوث مقاطعة،
وفي الأغلب مقاطعة زمنية.
وربما كان الحل يبدو فائق البساطة وسهل التحقيق في البداية، ولكن آثاره سيئة جدًا، لابل هي
أسوأ بكثير مما يمكن توقعه، فعملية حجب المقاطعات لايمكن أن تقوم بها البرمجيات 1. يجب إذا
إضافة استدعاء للنظام بهدف حجب وإعادة المقاطعات، وطلب هذا الاستدعاء أينما رأى المبرمج
حاجة لتعديل متحولات مشتركة.
وفي حال كانت هناك سلسلة متتالية من عمليات التعديل، أو كان التعديل ضمن حلقة ستنفذ
10000 مرة:
فهل سنقوم بحجب المقاطعة وإعادتها 10000 مرة ؟
أم أننا سنحجب المقاطعات في بداية الحلقة ونعيدها في النهاية ؟
ومن سيقرر ذلك ؟
1 في حال استخدام البوابة التسلسلية لقراءة محارف، فإن الزمن الحدي لقراءة حرف وارد على خط يعمل
هو من مرتبة 1ميلي ثانية، أي أننا لو لم نستجب للمقاطعة في هذا الزمن، فسيضيع baud بسرعة 9600
الحرف.
4
هل هو المبرمج ؟
؟ وهل سينتج عن ذلك ضياع لبعض المقاطعات التي لن تعالج في الوقت المناسب 2
أسئلة كثير نحن بغنى عنها، وتؤكد أن مبدأ السماح للتطبيقات بحجب المقاطعات سواء مباشرة أو
عن طريق استدعاء النظام هو عملية غير مأمونة العواقب . بالإضافة أن هذا الحل لايعمل في
منظومة متعددة المعالجات.
هناك حل آخر قد لايضمن ذرية التعليمة، ولكنه يحقق الغرض المطلوب . فنحن في الحقيقة يمكن
تعليمات أخرى، ولكن A1 A أي أن تتخلل التعليمتين 2 ، X++ أن نقبل مقاطعة تنفيذ التعليمة
لايجوز أن تكون هذه التعليمات جزءًا من عملية إضافة أخرى على نفس المتحول.
وبالتالي يمكن صياغة ضابط أقل حدة من الذرية لتنفيذ التعليمة:
لايجوز أن تقوم إجرائية أخرى بتعديل المتحول طالما لم تنته الإجرائية من تعديله.
ونصل أخيرًا إلى الخاصة الواجب تحقيقها لضمان صحة تنفيذ الإجرائيات المتواردة:
يجب أن يكون بإمكان المبرمج تعريف مجموعة من التعليمات
التي لايمكن أن تقوم بتنفيذها أكثر من إجرائية واحدة في
لحظة ما.
مثال على ذلك : إذا افتر ضنا مجموعة التعليمات المسؤولة عن إرسال ملف للطباعة، فلايجوز أن
تكون هناك أكثر من إجرائية واحدة تقوم بتنفيذ هذه التعليمات في لحظة ما، وإلا تداخلت
Critical المعلومات في الصفحة المطبوعة. ونسمي هذا النوع من التعليمات بالمقطع الحرج
.Section
إن خاصة المقطع الحرج هي أقل تطلبًا وأثرًا على النظام من خاصة الذرية التي ناقشناها أعلاه،
بالإضافة إلى كونها أكثر شمولية، إذ لاتشمل تعليمة واحدة بل مجموعة تعليمات . ومن الممكن
للمبرمج مث ً لا أن يقوم بتعريف إجراء ما ويطلب أن ينفذ هذا الإجراء بأكمله كمقطع حرج.
ويبقى إذا السؤال الهام والحيوي الذي يحتاج إلى حل: كيف يتم نحقيق المقاطع الحرجة ؟
2 First In First Out
5
المقاطع الحرجة
رأينا في المقطع السابق أن إمكانية تعريف مجموعة تعليمات كمقطع حرج تمثل الحل الأفضل
لمشكلة تداخل تنفيذ الإجرائيات مع بعضها
البعض. ويجب تحقيق الشروط التالية لضمان
حسن عمل المقاطع الحرجة:
لايجوز أن يؤجل دخول إجرائية إلى مقطع
حرج ما لم تكن هناك إجرائية أخرى تعمل
داخلة.
لا توجد أية فرضيات بخصوص سرعة عمل
الإجرائيات أو عددها.
تبقى الإجرائيات داخل المقطع الحرج لزمن
منته.
تحقيق المقاطع الحرجة
سنحاول فيما يلي تجربة الطرق المختلفة لتحقيق المقاطع الحرجة.
المحاولة الأولى:
دعونا نحاول المحاولة الأولى باستخدام الانتظار النشط:
تختبر الإجرائية باستمرار في حال كان بإمكانها دخول المقطع الحرج
لايمكن للإجرائية القيام بأي شيء طالما لم تحصل على السماح لدخول
المقطع الحرج.
هو تابع يعيد نتيجة CheckCriticalSectionPermission وهذا ما توضحه الأسطر التالية، ب اعتبار
إذا كان بإمكان الإجرائية true
الطالبة الدخول إلى المقطع
الحرج.
المحاولة الثانية:
يمكن لكل إجرائية اختبار حالة الإجرائيات الأخرى (قراءة فقط، بدون تعديل).
عند طلب الدخول إلى مقطع حرج، تقوم الإجر ائية بفحص حالة الإجرائيات الأخرى للتأكد
While(!CheckCriticalSectionPermission();
//loop until we get the permission
CS code follows……….
6
من عدم كونها داخل المقطع الحرج.
في حال عدم وجود إجرائيات أخرى، تقوم الإجرائية بتعديل حالتها لإعلام باقي
الإجرائيات بأنها داخل المقطع.
تكمن المشكلة هنا في احتمال حصول تبديل للإجرائيات في المعالج بين المرحلتين 2 و 3، كما
يظهر المثال التالي.
لو تم تغيير الإجرائيات مباشرة بعد نجاح اختبار الإجرائية الأولى، وقبل تعديل حالتها،
وسلمت وحدة المعالجة إلى
الإجرائية الثانية التي لن ترى أن
الإجرائية الأولى قد دخلت ,
وبالتالي ستقوم بدورها بدخول
المقطع الحرج . فإذا عاد التنفيذ
إلى الإجرائية الأولى قبل انتهاء
الثانية من تنفيذ المقطع الحرج،
ستكون هناك إجرائيتان داخل
المقطع الحرج لأن الإجرائية
الأولى ستتابع تنفيذها من حيث توقفت. أي أن هذا الحل غير مقبول.
المحاولة الثالثة:
لاحظنا في المرحلة السابقة أن العملية فشلت بسبب الفصل بين الاختبار والتعديل وعدم إمكا نية
جمعهما في تعليمة واحدة، ويحاول الحل التالي معالجة هذه المشكلة:
تقوم الإجرائية بوضع حالتها بأنها داخل المقطع الحرج
توقف الإجرائية تلقائيًا في حال وجود إجرائية أخرى داخل المقطع الحرج، ولايسمح لها
بالمتابعة إلا بعد انتفاء هذا الشرط
ويبدو لنا ثانية أن هذا الحل ممكن ولن يتكرر الخطأ الذي رأيناه في الحالة السايقة، ولكن حالة
Process 1 Process 2
2-While
(!AllOtherProcessOutsideCS())
While
(!AllOtherProcessOutsideCS())
1- Process1 pass 3- Process2 pass
5- Process1.Status = InsideCS; 4- Process2.Status = InsideCS;
CS code follows………. CS code follows……….
7
أخرى لاتقل خطورة يمكن أن تحصل، كما يظهر في المثال التالي.
لو تم تغيير الإجرائيات مباشرة بعد نجاح اختبار الإجرائية الأولى، وقبل تعديل حالتها،
وسلمت وحدة المعالجة إلى
الإجرائية الثانية التي لن ترى أن
الإجرائية الأولى قد دخلت ,
وبالتالي ستقوم بدورها بدخول
المقطع الحرج . فإذا عاد التنفيذ
إلى الإجرائية الأولى قبل انتهاء
الثانية من تنفيذ المقطع الحرج،
ستكون هناك إجرائيتان داخل
المقطع الحرج لأن الإجرائية
الأولى ستتابع تنفيذها من حيث توقفت. أي أن هذا الحل غير مقبول.
المحاولة الرابعة:
في محاولة لتلافي الاستعصاء الذي ظهر في المقترح السابق، يتم التعديل بالشكل التالي:
تقوم الإجرائية بالتعبير عن رغبتها في الدخول إلى المقطع الحرج وتعدل حالتها بناء
على ذلك.
تفحص الإجرائية حالة باقي
الإجرائيات، وتدخل المقطع في حال عدم
وجود طلب من إجرائيات أخرى.
في حال وجود الطلب، تقوم
الإجرائية بإلغاء رغبتها وإعادة الكرة من
جديد، وذلك حتى تدخل المقطع الحرج.
Process 1 Process 2
2-While
(!AllOtherProcessOutsideCS())
While
(!AllOtherProcessOutsideCS())
1- Process1 pass 3- Process2 pass
5- Process1.Status = InsideCS; 4- Process2.Status = InsideCS;
CS code follows………. CS code follows……….
8
وإن كان هذا الحل مقبو ً لا من حيث أنه لايسمح لأكثر من إجرائية بالدخول إلى المقطع الحرج،
ولكنه غير فعال، إذ ستقضي الإجرائيات على الأ غلب الكثير من الوقت في إعادة الإنتظار حتى
.( تتمكن من الدخول (المرحلة 3
المحاولة الرابعة:
هناك مشكلة أخرى في السيناريو السابق : دعونا نتصور أن هناك إجرائيتان تعبر كل منهما عن
رغبتها في الدخول، ولكنها ترى أن الثانية تريد الدخول فتلغي طلبها، وتعيد الكرة . لايوجد ما
يمنع نظريًا من أن يتكرر هذا الوضع إلى مالانهاية، وهذا الوضع يعرف باسم المجاعة
حيث تبقى الإجرائيات تحاول دخول المقطع الحرج دون أن يتحقق لها ذلك . ومع ،starvation
أن احتمال حدوث هذه المجاعة شبه
معدوم، ولكن لايمكننا في أنظمة التشغيل
الاعتماد على الاحتما لات. وبالتالي فإن
هذا الحل غير محبذ البتة.
حل بيترسون:
الاعتماد على تعليمات خاصة:
لاحظنا سابقًا أن السبب الأساسي في الخلل هو
الفصل بين الاختبار والتعديل، ولذلك لجأنا إلى
التعديل قبل الاختبار وما يتبعه من تعقيدات . تدعم
العديد من الحواسيب، لاسيما تلك الت ي تدعم تعدد
bool TestAndSet(bool *addr)
{
bool res = *addr;
*addr = true;
return res;
}
9
تعمل على الشكل التا ثلي: تقرأ .TST AND SET LOCK (TSL) المعالجات، تعليمة تعرف باسم
التعليمة محتوى الذاكرة وتضعه ضمن سجل ثم تخزن قيمة لاتساوي الصفر ضمن عنوان
الذاكرة المعني . ولايمكن للمعالجات الأخرى التعامل مع العنوان المذكور حتى انتهاء تنفيذ
التعليمة. ويمكن تمثيل عمل هذه التعليمة بالإجرائية التالية على أن يكون عملها غير قابل
للمقاطعة.
ويكون دخول الإجرائية إلى المقطع الحرج على الشكل التالي:
ملاحظة:وهذه الطريقة صحيحة وتعمل في بيئة متعددة المعالجات، ولكنها بدورها تعاني من
مشكلة الانتظار النشط.
3. السيمافور
يعتبر السيمافور أحد أهم الأدوات البرمجية المستخدمة في التزامن بين الإجرائيات، وربما كان
أهمها على الإطلاق.
تعريف
ويشبه السيمافور الأعداد الصحيحة مع وجود ثلاث فوارق:
عند إنشاء سيمافور، يمكن تأسيسه بأي قيمة صحيحة نشاء، ولكن بعد ذلك فإن العمليات
الوحيدة المتاحة هي إضافة أو طرح 1 من قيمته، ولايمكن قراءة هذه القيمة.
عند إنقاص القيمة، إذا كانت النتيجة سالبة، فإن الإجرائية الطالبة يتوقف عملها (تأخذ
ولاتعود إلى العمل إلا بعد أن ترفع إجرائية أخرى من قيمة السيمافور . ،(blocked الحالة
.wait تعرف عملية الإنقاص باسم
إذا كانت قيمة السيمافور سالبة وتقوم إجرائية بزيادة القيمة، يتم إيقاظ إحدى الإجرائيات
.signal المتوقفة وتتابع عملها من نقطة التوقف. وتعرف عملية الزيادة باسم
ترتب الإجرائيات المتوقفة ضمن رتل ملحق بالسيمافور، ويدار الرتل بحسب مبدأ الترتيب
.(FIFO) الزمني 3
بعض الملاحظات الخاصة بالسيمافور:
3 First In First Out
while (TestAndSet(&lock) == true); //just wait,lock is set
Execute Critical section;
Lock = false; // unlock the critical section.
10
لايوجد عمومًا طريقة لمعرفة إذا كانت الإجرائية ستتوقف أم لا قبل إنقاص السيمافور.
عندما تقوم إجرائية بإيقاظ إجرائية أخرى، لاتوجد طريقة لمعرفة أي منهما ستستحوذ
على المعالج وتتابع عملها.
إذا كانت قيمة السيمافور موجبة، فه ذا يمثل عدد الإجرائيات التي بإمكانها إنقاص
السيمافور بدون أن تتوقف. وإذا كانت القيمة سالبة، فهي تمثل عدد الإجرائيات المنتظرة.
V للإنقاص و P هناك أيضًا تسميات أخرى لعملية الإنقاص والزيادة، والأكثر شيوعًا هي
للزيادة, وهي التسميات الأصلية التي اقترحها صاحب فك رة السيمافور . وكانت حجته في
ذلك أنه من الأفضل أن نستخدم اسمًا بدون معنى من أن نستخدم اسمًا معناه غير مناسب.
استخدامات السيمافور
يستخدم السيمافور على نطاق واسع في برمجة التطبيقات المتواردة، ومن أهم مزاياه وضوح
الحل مما يسهل التحقق من صحته , بالإضافة إلى دعم العديد من أنظمة التشغيل له وبفاعلية
عالية.
:Signaling التشوير
أبسط تطبيقات السيمافور، ويستخدم عادة عندما تريد إجرائية أن تخبر إجرائية أخرى
بأنه قد حدث أمر ما . ويسمح التشوير بالتأكد من عدم تنفيذ مقطع معين من البرنامج قبل
.serialization الانتهاء من تنفيذ مقطع آخر، وتسمى هذه العملية بالسلسلة
مثال على التشوير هو حاجة الإجرائية الثانية إلى بيانات تقوم الإجرائية الأولى بإعدادها
ولايمكنها المتابعة بدونها, ويوضح الشكل التالي التحقيق البرمجي لعملية التشوير.
:Rendezvous التواعد
التواعد هو عملية معممة عن التشو ير، بحيث تنتظر كلتا الإجرائيت ين الأخرى وتتابعان
عملهما سوية.
11
ويظهر الشكل التالي مثا ً لا عن عملية التواعد:
Process A Process B
Statement A1 Statement B1
Statement A2 Statement B2
أي أن .B بعد 1 A و 2 ،A بعد التعليمة 1 B والمطلوب في عملية التواعد أن تنفذ التعليمة 2
الإجرائيتان ستتوقفان عن العمل عند الوصول إلى السطر الثاني، ولن تتابعا العمل حتى تتأكد كل
واحدة منهما من الوصول الأخرى إلى نفس النقطة.
ونحتاج لحل هذه المسألة إلى سيمافورين كما نرى في الشكل التالي:
Process A Process B
Statement A1 Statement B1
SemAhere.Signal(); SemBhere.Signal();
SemBhere.Wait(); SemAhere. Wait ();
Statement A2 Statement B2
إن هذا النوع من التزامن مفيد جدًا، إذ أنه يعني في النهاية أن كل إجرائية تعرف أين وصلت
الأخرى، وهذا تزامن كامل بين الإجرائيتين.
قد يخطر على البال استخدام الحل التالي:
Process A Process B
Statement A1 Statement B1
SemBhere.Wait(); SemAhere. Wait ();
SemAhere.Signal(); SemBhere.Signal();
Statement A2 Statement B2
وهو حل سيئ جدًا، لأنه يؤدي إلى حصول استعصاء في المسألة، إذ ستنتظر كل من الإجرائيتين
أن تضيف الأ خرى السيمافور الخاص بها دون أن تتمكن من ذلك . وتعتبر مشكلة الاستعصاء
A1 B1 A2 B2
12
إحدى أهم العقبات التي تؤدي إلى فشل حلول مسائل التنسيق بين الإجرائيات . وإن كانت المشكلة
واضحة في هذه المسألة بالذات، لكن يمكن أن تكون أقل وضوحًا بكثير من ذلك.
الاستبعاد المتبادل
يعتبر ال سيمافور من افضل الأدوات لتحقيق الاستبعاد المتبادل الضروري لتنفيذ المقاطع الحرجة .
ونستخدم لذلك نوعًا خاصًا من السيمافورات يعرف باسم السيمافورات الثنوية
والسبب في تسميتها كذلك هي أن قيمة تاسيسها .Mutex أو أيضًا باسم ،Binary Semaphores
هي واحد. ويوضح الشكل التالي كيفية استخدام السيمافور لتحقيق الاستبعاد المتبادل:
Process A Process B
Mutex.Wait() Mutex.Wait()
//Critical Section code
X++
//Critical Section code
X++
Mutex.Signal () Mutex.Signal ()
في Wait بسبب خواص السيمافور التي سبق وأوضحناها، لايمكن لإجرائيتين أن ت عبرا تعليمة
آن واحد . وبالتالي فإن التعليمات المحصورة بين تعليمتي الإنقاص والإضافة تنفذ باستبعاد
متبادل.
لايسمح عادة بدخول أكثر من إجرائية إلى مقطع حرج، ولكن هناك حالات معممة يمكن أن نقبل
فيها أكثر من إجرائية ضمن مقطع حرج، مع وجود حد أعلى للإجرائيات . ويمكن أن نتعرض
لهذا الوضع عندما نحاول نمذجة مطعم لايسمح بدخول الزبائن إلا إذا كان لديه مكان لجلوسهم .
وفي حال وصوله إلى السعة الكلية، لايمكن دخول زبون جديد ما لم يخرج أحد الزبائن من
الداخل.
يمكن استخدام السيمافورات لحل هذه الحالة المعممة من المقاطع الحرجة . وذلك بتاسيس قيمة
السيمافور على الحد الأعلى للإجرائيات المسموح دخولها إلى المقطع الحرج.
13
الحواجز
هي مفهوم معمم عن التواعد، بحيث يكون عدد الإجرائيات المتواعدة اكثر Barriers الحواجز
. من اثنتين. ومشكلة الحل المعروض أعلاه أنه غير قابل للتعميم على أكثر من إجرائية 4
ويمكن استخدام نموذج الحاجز لحل كثير من المشكلات، مثال عنها هي مسائل المعالجة
التفرعية التي يتم تقسيم المسألة إلى عدد من الأجزاء وتكلف كل إجرائية بمعالجة جزء، ولاينتقل
إلى الخطوة التالية إلا بعد انتهاء كل الإجرائيات من معالجة الجزء الخاص بها . ويوضح الشكل
التالي آلية عمل الحواجز:
Process A Process B Process C
Rendezvous Rendezvous Rendezvous
Action action Action
ويظهر الحل التالي كيفية تنفيذ الحواجز باستخدام السيمافور: نفترض أن لدينا المتحولات التالية:
عدد الإجرائيات التي يجب أن تعبر
n الحاجز هو
4 من غير المعقول أن نستخدم 100 سيمافور في حال كنا نريد أن تتواعد 100 إجرائية
void waitbarrier()
{
//rendezvous
mutex.wait()
count = count + 1
mutex.signal()
if count == n: barrier.signal()
barrier.wait()
barrier.signal()
//action
}
14
count عدد الإجرائيات التي وصلت إلى الحاجز هو
وأساسه بالطبع واحد mutex هناك سيمافور مخصص للاستبعاد المتبادل
مؤسس على قيمة صفر، وهو يبقى مقف ً لا حتى يكتمل عدد barrier لدينا سيمافور آخر
الإجرائيات، وبعدها يفتح السيمافور مباشرة.
حتى يكتمل العدد، وعندها barrier عمل الحاجز بديهي، إذ تقف كل ا لإجرائيات عند السيمافور
تمر الإجرائيات واحدة تلو الأخرى، فكل واحدة تمر تفتح الطريق لمن بعدها.
حل مسائل شهيرة باستخدام السيمافور
هناك العديد من المسائل التي يمكن استخدامها كحالة نموذجية لدراسة السيمافور، وسنورد في
هذا المقطع عددًا منها.
:Producer-Consumer مسألة المنتج والمستهلك
هذه المسألة هي إحدى أشهر مسائل التزامن بين الإجرائيات . وهي مستخدمة في حل الكثير من
المسائل أكثر تعقيدًا. ومبدأ المسألة هو وجود إجرائيتين:
.buffer تنتج "أغراضًا" وتضعها ضمن خزان :Producer إجرائية منتجة
تسحب الأغراض من الخزان لتقوم باستهلاكها. :Consumer إجرائية مستهلكة
أحد أبسط الأمثلة هو الواجهة التخاطبية لنظام التشغيل، حيث يقوم المستخدم بتوليد العديد من
الأحداث مثل الضغط على زر لوحة المفاتيح أو نقر على الفأرة، ويكون بذلك منتجً ا. وتقوم
إجرائية أخرى بأخذ الأحداث المولدة واحدة تلو الأخرى ومعالجتها لتكون بذلك مستهلكًا.
. ويوجد موقع يوضحطريقة عمل هذه الخوارزمية 5
يمكن تلخيص ضوابط التزامن بين الإجرائيتين كما يلي:
تكون حالة الخزان خلال مرحلة الإضافة والسحب غير مستقرة، لذا يجب أن تتم هذه
العمليات ضمن مقطع حرج.
في حال طلبت إجرائية المستهلك سحب أغراض والخزان فارغ، يتعين عليها الانتظار
حتى يضع المنتج أغراضًا فيه.
يمكن أن يكون للخزان سعة قصوى، وفي هذه الحالة يتوقف المنتج عن العمل عند
الوصول إلى السعة القصوى حتى يسحب المستهلك أغراضًا.
لحل هذه المسألة نحتاج إلى سيمافورين:
5 http://gaia.ecs.csus.edu/~zhangd/oscal/ProducerConsumer/ProducerConsumer.html
15
.Mutex الأول يستخدم لتحقيق الاستبعاد المتبادل ويسمى
.Items الثاني يمثل عدد العناصر في الخزان ويسمى
برنامج المنتج:
يقوم المنتج بإنتاج غرض، ثم
يدخل المقطع الحرج ويضيف
عنصرًا إلى الخزان، ثم ينفذ
تعليمة الإضافة على السيمافور
ليزيد من عدد العناص ر items
في الخزان ويخرج من المقطع
الحرج، هذا الحل لايدعم السعة القصوى للخزان.
برنامج المستهلك:
قبل أن يقوم المستهلك باستهلاك غرض، يطلب
ليتأكد من وجود غرض items إنقاص السيمافور
في الخزان، وبعدها يدخل المقطع الحرج ليسحب
الغرض ومن ثم يخرج من المقطع الحرج.
يمثل ,capacity في حا ل أردنا إضافة مفهوم السعة القصوى، علينا استخدام سيمافور ثالث
الاماكن المتبقية ضمن الخزان، ويقوم المنتج بإنقاصه قبل الدخول إلى المقطع الحرج، كما يقوم
المستهلك بإضافته بعد انتهائه من الاستهلاك . وتصبح البرامج على الشكل التالي (الإضافة باللون
الأحمر):
void producer ( void )
{
while (true)
{
produce ( object );
wait ( mutex ); //mutex is semaphore
put (object);
signal ( mutex );
signal ( items );
}
}
void consumer (void)
{
while(true)
{
wait (items);
wait (mutex);
remove (object);
signal (mutex);
consume (object);
}
}
void producer ( void )
{
while (true)
{
wait (capacity);
produce ( object );
wait ( mutex );
// mutex is semaphore
put (object);
signal ( mutex );
signal ( items );
}
}
void consumer ( void )
{
while(true)
{
wait ( items );
wait ( mutex );
remove ( object );
signal ( mutex );
signal (capacity);
consume ( object );
}
}
16
قبل الدخول في المقطع الحرج وليس capacity ملاحظة هامة : لماذا نقوم بإنقاص السيمافور
بداخله ؟ هل هناك فرق في النتيجة ؟ والجواب.
بكل بساطة هو نعم . في حال إنقاص السيمافور داخل المقطع الحرج ، فإننا نتعرض إلى
استعصاء في النظام إذ قد تتوقف إجرائية المنتج عن د هذا السيمافور بسبب الوصول إلى السعة
القصوى. وفي هذه الحالة لن تتمكن من تحرير المقطع الحرج، وستبقى كافة الإجرائيات
الأخرى منتظرة عند مدخل المقطع الحرج ولن تتمكن من الدخول وبالتالي تتوقف كافة مكونات
المسألة عن العمل.
:Readers-Writers مسألة الكتاب والقراء
تسمح هذه المسألة بنمذجة الكثير من بنى المعطيات المعرضة للقراءة والتعديل من قبل عدد كبير
من الإجراءات المتواردة، كقواعد البيانات مث ً لا. وتلخص ضوابط التزامن لهذه المسألة على
الشكل التالي:
يمكن لأي عدد من الإجرائيات التي ترغب في القراءة بالتواجد داخل المقطع الحرج.
تحتاج الإجرائية التي تقوم بالتعديل إلى الولوج الحصري إلى البنى المراد تعديلها،
وبالتالي يجب أن تكون وحيدة داخل المقطع الحرج.
أي يمكننا القول أنه لايمكن للإجرائية طالبة التعديل دخول المقطع الحرج في حال وجود أية
إجرائية أخرى تقوم بالقراءة أو الكتابة . وعندما تكون هذه الإجرائية في داخل المقطع الحرج،
فإنها تمنع أية إجرائية أخرى من الدخول، سواء بهدف القراءة أو الكتابة.
. ويوجد موقع يوضح طريقة عمل هذه الخوارزمية 6
يمثل عدد الإجرائيات التي تقوم readers نستخدم من أجل الحل المتحولات التالية : عداد
تكون CSEmpty وسيمافور ثاني ،mutex بالقراءة، وسيم افور مسؤول عن حماية العداد المذكور
قيمته واحد إذا لم تكن هناك أية إجرائية داخل المقطع
الحرج، وصفرًا في حال وجود أية إجرائية أخرى داخل
المقطع الحرج.
حل إجرائية الكاتب بسيط جدًا، ينتظر الكاتب عدم وجود أية إجرائية داخل المقطع الحرج، وذلك
.CSEmpty باستخدام السيمافور
أما بشأن القارئ فالموضوع معقد بعض الشيء، إذ يجب عدم الدخول في حال وجود كاتب، كما
يجب عدم منع القارئين الآخرين من الدخول في حال تمكنت الإجرائية من ذلك . ويمكن تلخيص
6 http://gaia.ecs.csus.edu/~zhangd/oscal/ReaderWriter/ReaderWriter.html
int readers = 0;
mutex = Semaphore(1);
roomEmpty = Semaphore(1);
17
فكرة الحل في أن أول قارئ يدخل
يوصد الباب في وجه الكت اب،
وآخر قارئ يخرج يفتح الباب
للكتاب المنتظرين.
لايحوي الحل احتمال وجود
استعصاء، ولكن تظهر لدينا هنا
مشكلة جديدة قد لاتقل خطورة عن
الاستعصاء، وتعرف باسم المجاعة
إذ من الممكن أن يصل كاتب وينتظر بسبب وجود قراء في الداخل . ويبقى الكاتب ،starvation
ينتظر الدخ ول إلا مالانهاية بينما يتوافد القراء ويخرجون ويبقى هناك على الأقل قارئ واحد
يمنع الكاتب من الدخول.
يمكن تعديل الحل لتفادي هذه المشكلة بالشكل التالي:
كافة القراء الذين يصلون بعد وصول الكاتب المنتظر لايدخلون المقطع الحرج، بل ينتظرون
انتهاء الكاتب ليدخلوا، و بذلك يكون انتظار الكاتب منتهيًا، إذ عليه فقط انتظار خروج القراء
الذين كانو موجودين لحظة وصوله.
:Dining philosophers مسألة عشاء الفلاسفة
ربما كانت هذه المسألة أكثر مسائل السيمافور شعبية، إذ لا يمكن أن يصدر كتاب عن أنظمة
التشغيل دون التطرق إليها، وكلما ظهرت آلية جديدة من آليات التزامن، يهرع أصحابها إلى
إظهار سهولة حل مسألة الفلاسفة باستخدام هذه الآلية.
يجلس خمسة فلاسفة في حلقة حول طاولة، وأمام كل منهم طبق من المعكرونة لاينتهي محتواه،
وهناك شوكة بين كل صحنين، أي أن أمام كل فيلسوف شوكتان : واحدة على يمينه وأخرى على
يساره.
يقضي الفيلسوف حياته في التفكير وتناول الطعام من طبق
المعكرونة، وليتمكن من تناول الطعام يحتاج إلى تناول
الشوكتين ليتمكن من الأكل . وبعد الإنتهاء من الأكل،
ينظف الفيلسوف الشوكتين ويعيدهما إلى مكانهما جاهزتين
للاستخدام من جديد .
mutex.wait()
readers += 1
if readers == 1:
roomEmpty.wait() # first in locks
mutex.signal()
# critical section for readers
mutex.wait()
readers -= 1
if readers == 0:
roomEmpty.signal() # last out unlocks
mutex.signal()
P0
P3
P2
P1
P4
18
. ويوجد موقع يوضح طريقة عمل هذه الخوارزمية 7
يعتمد الحل البديهي على تمثيل كل شوكة بسيمافور قيمته الأساسية واحد، بحيث تمثل عملية
الإنقاص حجز الشوكة، وعملية الزيادة تحرير
قبل تناول الطعام i الشوكة. ويقوم الفيلسوف رقم
الذي يقوم بطلب GetForks(i) باستدعاء الإجراء
عن طريق إنقاص كل من ، i+ و 1 i الشوكتين رقم
السيمافورين الموافقين . وبعد الإنتهاء من تناول
الطعام، يقوم الفيلسوف باستدعاء الإجراء
الذي يقوم بزيادة ، ReleaseForks(i)
السيمافورين الذين سبق إنقاصهما.
للأسف فإن الحل البديهي غير مقبول، إذ يمكن أن يحصل
استعصاء في الحالة التالية: دعونا نتصور أن كل إجرائية
بين إجرائيات الفلاسفة حجزت الشوكة على يمينها، وتم
تبديل المعالج قبل أن تحجز الشوكة على يسارها. سنجد
نفسنا في وضع يحمل فيه كل فيلسوف شوكة في يده اليمنى
دون أن يتمكن من الحصول على الشوكة الأخرى لأنها
محجوزة، وهذا يمثل استعصاء.
نقترح لحل الاستعصاء أن يقوم الفيلسوف باختبار حالة الشوكة التي على يساره قبل التورط
بمحاولة إنقاص السيمافور، فإذا كانت الشوكة محجوزة يقوم بإعادة الشوكة على يمينه إلى
الطاولة، ويعيد طلب الشوكتين من جديد . هذا الحل يعقد الأمور بعض الشيء، إذ أنه يخالف أحد
المبادئ الأساسية في السيمافور : لايمكننا معرفة قيمة السيمافور، كل ما يمكننا هو طلب
الإنقاص، فإذا كانت قيمة السيمافور صفرًا أو أقل يتوقف تنفيذ الإجرائية . بالإضافة إلى كونه
يعاني من مشكلة المجاعة، إذ من الممكن أن يتكرر الوضع إلى مالانهاية.
ملاحظة ه امة جدً ا: إن احتمال ظهور المجاعة أو الاستعصاء هو شرط كاف لرفض الحل أو
اعتباره غير مرغوب فيه، وذلك مهما كان الاحتمال ضئي ً لا.
هناك العديد من الحلول التي لاتعاني من مشكلة الاستعصاء، وسنقتصر هنا على الحلول
الأساسية فقط.
7 http://www.doc.ic.ac.uk/~jnm/concurrency/classes/Diners/Diners.html
Semaphore fork[5] = 1;
void GetForks(int i) {
fork[i].down();
fork[i+1].down();
}
void ReleaseForks(int i) {
fork[i].up();
fork[i+1].up();
}
19
يظهر الشكل التالي ح ً لا يعتمد على كسر حلقة الانتظار التي تسبب الاستعصاء.
فالسبب في ظهور الاستعصاء يعود إلى تشكل
حلقة في بيان الانتظار الذي يمكن بناؤه باستخدام
القاعدة البسيطة : إذا افترضنا أن الإجرائيات
تشكل نقاطًا ضمن بيان، يرسم قوس من النقطة
لأن B تنتظر A في حا ل كون B باتجاه النقطة A
الحصول عليه . والحل المطروح هنا يتلخص في وجود فيلسوف واحد A حجزت موردًا تريد B
"أعسر"، يطلب الشوكة اليسرى قبل اليمنى . وفي هذه الحالة، لن تتكون الحلقة ولن يحصل
استعصاء.
هذا الحل ممتاز لهذه المسألة، ولكنه غير قابل للتعميم بسهولة في مسائل أ خرى غير مسألة
الفلاسفة، إذ يحتاج إلى وضع تصور دقيق لبيان الانتظار واحتمالات تشكل الحلقات ضمنه.
حل آخر يستند على مبدأ الحد من عدد الإجرائيات التي تتنافس على الموارد بحيث يكون لدينا
دومًا ما يكفي من الموارد للمحافظة على عمل النظام . في حالة عشاء الفلاسفة، يم كننا بسهولة
إثبات أنه لو سمحنا فقط لأربعة فلاسفة بتناول
الطعام عوضًا عن الخمسة، فلن يكون هناك
استعصاء. إذ في أسوأ الحالات، سيكون لدينا
أربعة فلاسفة يحمل كل منهم شوكة، وستبقى
شوكة غير محجوزة، مع وجود فيلسوف على
P1
P5
P4
P3
P2
w
ait
in
w
ait
in
waitin waitin
waitin
void LeftHandedGetForks(int i)
{
fork[i+1].down();
fork[i].down();
}
void GetForks(int i)
{
footman.wait()
fork[right(i)].wait()
fork[left(i)].wait()
}
void ReleaseFors(int i)
{
fork[right(i)].signal()
fork[left(i)].signal()
footman.signal()
}
20
اليمين وآخر على اليسار يحمل كل منهما شوكة ومس تعد لأخذ الشوكة المتاحة . يمكننا أيضًا
إثبات أن هذا الحل لايحوي على مجاعة.
ولتقييد عدد الإجرائيات التي يمكن أن تأكل في نفس الوقت، نقوم بإضافة سيمافور جديد مؤسس
على القيمة (عدد الفلاسفة- 1). وهذا الحل مبين في الشكل التالي:
الذي قدمه في Andrew Tanenbaum الحل الأخير يعرف باسم حل تانينبوم، نسبة إلى صاحبه
كتابه الذي يعد من أشهر كتب أنظمة التشغيل . يعتمد الحل على فكرة شبيهة بالمبدأ الأساسي
الذي من أجله أوجد السيمافور:
عدم الفصل بين الاختبار والتعديل. إن المشكلة التي يعاني منها الحل الأول سببها الفصل بين
عمليتي الحجز.
ومنه مقترح الحل:
حجز الشوكتين في آن واحد، فإما يحصل الفيلسوف على الشوكتين، أو يبقى منتظرًا دون أن
يحجز إحداهما . وبتعبير آخر، يمكن للفيلسوف تناول الطعام في حال كون جاريه الاثنين
لايأكلان.
الحل
لايوجد استعصاء في هذا الحل لأن السيمافور الوحيد الذي يمكن اس تخدامه من قبل أكثر من
ولاتقوم أية إجرائية بإجراء عملية قد ينتج عنها ،mutex إجرائية هو سيمافور الاستبعاد المتبادل
انتظار داخل المقطع الحرج . وبالمقابل، أثبت أن هذا الحل يعاني من مشكلة المجاعة، ولكننا لن
ندخل في تفاصيل ذلك بسبب التعقيد المرتبط بذلك.
في هذا الحل لم نعد بحاجة لتمثيل كل شوكة بسيمافور، وإنما نعتمد على التمثيل التالي:
مصفوفة من خمسة متحولات يمثل كل منها حالة فيلسوف، ويمكن للفيلسوف أن يأخذ
حالة التفكير أو الجوع أو تناول الطعام (السطر الاول من الكود في الشكل التالي).
مصفوفة من خمسة سيمافورات مؤسسة على الصفر، يستخدم كل منها لجعل الفيلسوف
الموافق ينتظر (السطر الثاني من الكود في الشكل التالي).
سيمافور واحد يستخدم لحماية المتحولات المذكورة أعلاه من التغيير بدون تنسيق
(السطر الثالث من الكود في الشكل التالي).
ويكون الحل على الشكل التالي:
21
i وهو يقوم بفحص ما إذا كان بإمكان الفيلسوف رقم ،test(i) العملية الأساسية هي في التابع
أن يتناول الطعام، وفي حال الإيجاب، تتم إضافة السيمافور الخاص بانتظار الفيلسوف المعني.
هناك طريقتان يمكن لفيلسوف أن يتناول الطعام فيها:
يمكن أن يطلب الحصول
على الشوكتين ويجد أنهما
غير محجوزتين أي لا أحد
من الجارين يأكل،
فيحجزهما ويبدأ الطعام.
أو يمكن أن تكون إحدى الشوكتين محجوزة أي أحد الجارين يأكل ، وفي هذه الحالة
لايمكن للفيلسوف المتابعة ويتوقف بانتظار أن يتغير الوضع . فعندما ينتهي كل فيلسوف
من تناول الطعا م، يقوم باختبار إذا كان جاراه راغبين في تناول الطعام ويضع الشوكتين
تحت تصرفهما.
state = ['thinking']*5
sem = [Semaphore(0) for i in range(5)]
mutex = Semaphore(1)
The initial value of state is a list of 5 copies of 'thinking'.
sem is a list of 5 semaphores with the initial value 0.
void test(int ai)
{
if (state[i] == hungry and_
state (left (i)) != eating and_
state (right (i)) != eating)
state[i] = eating
sem[i].signal()
}
22
ملاحظة.
Monitor 4. المراقب 8
رغم سهولة استخدام السيمافور وتوافره في كافة أنظمة التشغيل، وكونها كافية لحل جميع
C مشكلات التزامن التي يمكن أن توا جهنا، فإنها تبقى "منخفضة المستوى ". ويمكن مقارنتها بلغة
في البرمجة، وهي لغة تسمح ببرمجة كافة التطبيقات التي نريدها، إلا أنها لاتحوي على العديد
من المفاهيم التي تريح المبرمج . وبنفس الطريقة، فإن الحلول باستخدام السيمافور غالبًا ما تكون
طويلة وتحتاج إلى دقة كبيرة، ويمكن أن تؤدي أخطاء بسيطة فيها إلى ظهور استعصاءات أو
مجاعة.
ورغم استخدام السيمافور لتحقيق المقاطع الحرجة، فإن العملية تبقى يدوية ومعتمدة على وضع
تعليمات السيمافور في الموقع المناسب، ويبقى التأكد من صحة البرنامج متروكًا كليًا على عاتق
المبرمج.
8 قد يكون المصطلح غير مقنعًا، ولكن لايوجد بديل له في الوقت الراهن
state = ['thinking'] * 5
sem = [Semaphore(0) for i in range(5)]
mutex = Semaphore(1)
The initial value of state is a list of 5 copies of 'thinking'.
sem is a list of 5 semaphores with the initial value 0.
void GetForks(int i)
{
mutex.wait();
state[i] = hungry;
test(i);
mutex.signal();
sem[i].wait();
}
void ReleaseForks(int i)
{
mutex.wait();
state[i] = thinking;
test(right(i));
test(left(i));
mutex.signal();
}
void test(int ai)
{
if (state[i] == hungry and
state (left (i)) != eating and
state (right (i)) != eating)
state[i] = eating
sem[i].signal()
}
}
23
المراقب هو أداة أعلى مستوى من السيمافور، تسمح بتعريف المقطع الحرج بشكل تلقائي وبدون
حصول أخطاء في تحقيقها . ويتكون المراقب من بيانات على شكل مجموعة متحولات، بالإضافة
إلى إجراءات تتعامل مع هذه المتحولات . يحوي المراقب أيضًا على متحولات من نوع خاص
.conditions يسمى الشروط
يحقق المراقب ومتحولاته الخصائص التالية:
لايمكن التعامل مع بيانات المراقب إلا باستخدام الإجراءات الخاصة بالمراقب
تعمل الإجراءات باستبعاد متبادل بين بعضها البعض، أي لايمكن في لحظة ما أن يكون
هناك أكثر من إجراء واحد داخل المراقب.
.signal و wait يمكن التعامل مع متحولات الشروط عبر تعليمتين فقط، وهما
على نفس signal إلى توقف الإجرائية الطالبة بانتظار وصول تعليمة wait تؤدي عملية
المتحول.
إلى متابعة إجرائية واحدة متوقفة عند الشرط الموافق، وفي حال signal تؤدي عملية
عدم وجود إجرائية متوقفة، لايكون لها أي مفعول.
إلى تحرير المراقب بحيث يكون بإمكان إجرائية ثانية تنفيذ wait يؤدي طلب تعليمة
تلقائيًا P يتوقف عمل Q إجرائية أخرى P إجراءات المراقب. فإذا أيقظت إجرائية
من Q بانتظار خروج
المراقب أو توقفها عند
شرط آخر.
ويوجد موقع يوضح طريقة
. عمل هذه الخوارزمية 9
ويظهر الشك ل التالي ح ً لا
لمسألة المنتج والمستهلك
باستخدام خزان منتهى السعة
مكتوبًا باستخدام مراقب.
ونلاحظ أن كتابة الحل أسهل
بكثير من استخدام السيمافور،
9 http://gaia.ecs.csus.edu/~zhangd/oscal/monitor/monitor.html
monitor BoundedBuffer
{
private Buffer b = new Buffer(10);
private int count = 0;
private Condition nonfull, nonempty;
public void add(Object item)
{
if (count == 10) nonfull.wait();
b.add(item);
count++;
nonempty.signal();
}
public Object remove()
{
if (count == 0) nonempty.wait();
item result = b.remove();
count--;
nonfull.signal();
return result;
}
}
24
إذ ليس على المبرمج أن يحاول حماية متحول بعينه أو مجموعة تعليمات محددة . وذلك لأن
الإجراء بأكمله ينفذ باستبعاد متبادل.
هذه الخاصة الأخيرة ضرورية لضمان صحة عمل الإجرائيات، إذ أنها تعطي المنتظر أولوية
على المحرر، وذلك بهدف السماح للمنتظر بمتابعة العمل مباشرة دون معاودة التحقق من صحة
هي التي ستتابع العمل، فربما قامت بتنفيذ P الشرط الذي توقف من أجله. فلو كانت أجرائية
بالمتابعة . وهذا يؤدي للأسف إلى مشكلة في أداء Q تعليمات تغير من الشرط الذي سمح ل
المراقب بسبب كثرة عمليات التبديل بين الإجرائيات.
دعونا نأخذ مثال الخزان أعلاه ونلاحظ ماسيحصل عندما تتوقف إجرائية عند الشرط
.Add وتقوم إجرائية أخرى بتنفيذ إجراء ،nonempty
nonempty.signal() يضيف المنتج الغرض إلى الخزان ويستدعي .i
يتوقف المنتج مباشرة عن العمل ويتابع المستهلك العمل .ii
يسحب المستهلك الغرض من الخزان ويترك المراقب .iii
هي آخر تعليمة في الإجراء، signal يتابع المنتج عمله، وباعتبار أن تعليمة .iv
يخرج المنتج من المراقب.
هناك عملية تبديل في السياق بين المنتج والمستهلك وبالعكس، وهي تؤدي إلى الحد من أداء
كبديل notify النظام ككل في حال الاعتماد الكثيف على المراقبين . ولتلافي ذلك، أضيفت عملية
تتابع عملها دون توقف، notify والفرق بينهما هو أن الإجرائية التي تطلب .signal عن تعليمة
إلى إعادة اختبار الشرط الذي توقفت notify بينما تحتاج الإجرائ ية المتوقفة والتي حررتها عملية
من أجله من جديد. وبالتالي فإن الاختبار السابق الذي كان:
والذي كان اختبارًا لمرة واحدة،
يجب أن يتحول إلى حلقة ليصبح:
if (count==10)
{
nonfull.wait();
}
while (count==10)
{
nonfull.wait();
}
25
لايوجد في لغات البرمجة
تحقيق شائع للمراقبين، ولكن
هناك مايشبه ا لمراقب في لغة
جافا، وهو الطرائق المتزامنة
.synchronized methods
والفرق هو أننا لانحتاج في
لغة جافا إلى توصيف صف
معين من الأغراض على أنه
مراقب، فكل غرض مرشح
ليكون مراقبًا. ويحقق
التزامن عن طريق الطرائق
المتزامنة التي تنفذ تلقائيًا
باستبعاد متبادل، كما أن
جافا لاتحوي متحولات
شروط مثل تلك الموجودة
و c.wait() في المراقب، بل هناك متحول واحد مضمر غير معرف . فعوضًا عن كتابة
ويظهر الشكل الجانبي ح ً لا لمسألة المنتج والمستهلك .notify() و wait() نكتب ببساطة ،c.notify()
باستخدام خزان منتهى السعة مكتوبًا بلغة جافا.
ملاحظة.
والذي يقوم بإيقاظ كافة الإجرائيات المتوقفة بسبب notifyall() ونلاحظ أننا نستخدم هنا إجراء
التي بحسب توصيف جافا توقظ إجرائية واحدة غير محددة . notify عوضًا عن ،wait تنفيذ
فلايمكننا أن نضمن مث ً لا أن الإجرائية التي ستستيقظ بعد إضافة عنصر هي إجرائية متوقفة في
انتظار وجود عناصر ضمن الخزان.
5. الرسائل
استندت كافة آليات التزامن السابقة على وجود متحولات مشتركة بين الإجرائيات، ولكن ماذا
يحصل لولم تكن هناك ذاكرة مشتركة ؟
الحاجة إلى الرسائل:
class BoundedBuffer
{
private List b = new ArrayList(10);
private int count = 0;
synchronized public void add(Object item)
{
while (count == 10)
{
wait();
}
b.add(item);
count++;
notifyAll();
}
synchronized public Object remove()
{
while (count == 0)
{
wait();
}
Object result = b.remove(0);
count--;
notifyAll();
return result;
}
}
26
لم تعد المشكلة هي في إلغاء التضارب بين الإجرائيات، ولكن في تأمين آلية اتصا ل وتعاون
بينها. نستخدم لهذا الغرض آلية أخرى هي الرسائل، وهي موجودة في جميع أنظمة التشغيل،
والشكل العام لآلية الرسائل هو وجود إجرائين خاصين لهذا الغرض:
send(destination, message) إرسال
receive(source, message_buffer) استقبال
ويختلف تحقيق هذه الإجراءات من نظام لآخر.
. ويوجد موقع يوضح طريقة عمل هذه الخوارزمية 10
متغيرات تحقيق الرسائل: التسمية:
يمكن تحديد المصدر والوجهة مباشرة باستخدام هوية الإجرائية، أو بشكل غير مباشر باستخدام
وهناك العديد من الأسماء المستخدمة .message queue أو رتل رسائل mailbox علبة بريد
لتسمية علبة البريد في الأنظمة المختلفة، ولكنها جميعها تعمل بحسب المبدأ نفسه : خزان رسائل
يسمح بإضافة وسحب الرسائل بحسب آلية المنتج والمستهلك، وعلى الأغلب يكون سحب
الرسائل بنفس ترتيب وصولها . يمكن أيضًا أن تكون علبة البريد مخصصة لإجرائية واحدة
وتسمى في هذه الحالة بوابة.
كما أن الاستلام ،Multicast تسمح بعض الأنظمة بإرسال رسالة إلى عدة إجرائيات في آن واحد
غالبًا ما يكون مفتوحًا، أي يمكن للمستلم أن يستلم رسالة من أية إجرائية، وليس من إجرائية
بعينها.
anycast multicast
broadcast unicast
متغيرات تحقيق الرسائل: التزامن:
القاعدة الأكثر شيوعًا هي أن تكون عملية الإرسال غير موقفة، أي أن المرسل يرسل رسالته
ويتابع عمله بغض النظر عن كون المستقبل قد حصل عليها أم لا . أما عملية الاستقبال فهي
موقفة لأن الإجرائية لا تتابع عملها قبل انتهاء الاستقبال وحصولها على البيانات . وفي هذه
10 http://gaia.ecs.csus.edu/~zhangd/oscal/message/message.html
27
الحالة لايكون هناك تزامن حقيقي بين المرسل والمستقبل لأن المرسل لايعرف إذا كان المستقبل
قد حصل على رسالته أم لا.
وفي هذه .Rendezvous النوع الآخر هو الرسائل المتزامنة التي تعمل بحسب مبدأ الموعد
الحالة يتوقف المرسل والمستقبل ولايتابعان عملهما إلا بعد وصول الرسالة إلى المستقبل.
متغيرات تحقيق الرسائل: التخزين:
نظرًا لوجود فصل بين فضاء العنونة الخاص بالإجرائيات، يقوم نظام التشغيل بنسخ الرسالة في
ذاكرة داخلية خاصة به قبل نسخها ثانية في مساحة الذاكرة الخاصة بالمستقب ل. ومن الممكن ألا
يسمح نظام التشغيل بتخزين الرسائل بالمرة، ويقوم بتسليمها مباشرة للمستقبل . وفي هذه الحالة،
تكون كافة الرسائل المرسلة متزامنة لأن المرسل سيضطر إلى التوقف في انتظار المستقبل.
استخدامات الرسائل
تستخدم الرسائل في بناء العديد من التطبيقات الها مة، ولاسيما تطبيقات المخدم /الزبون
والتطبيقات الموزعة التي لاتتوافر فيها في أغلب الأحيان ذاكرة مشتركة بسبب كونها تعمل على
حواسيب مختلفة.
تستخدم الرسائل أيضًا كأداة للاتصال والتزامن بين الإجرائيات في أنظمة التشغيل المركزية غير
الموزعة، وذلك كبديل عن آليات ال ذاكرة المشتركة ومشكلاتها التي سبق واستعرضناها في هذا
الفصل، أو كآلية للاتصال المحمي بين الإجرائيات التي لاتثق ببعضها البعض.
بحيث UNIX صمم نظام التشغيل
يستخدم الرسائل كآلية أساسية
للاتصال بين الإجرائيات . إذ لاتوجد
ذاكرة مشتركة بين الإجرائيات ولكنها
تتصل بي ن بعضها البعض باستخدام
وهي عبارة عن قناة ،pipes المواسير
للاتصال بين مرسل ومستقبل توصل
الرسائل بحسب ترتيب إرسالها .
ويمكن للمرسل أن يكتب فيها كما
التسمية هنا غير مباشرة، .read ويقرأ منها المستقبل وكأنه يقرأ من ملف ،write يكتب في ملف
إذ يمكن تشبيه المواسير بأرتال الرسائل. أما فيما يخص التزامن فهو يطبق القاعدة الشائعة:
Client
Client
Client
Client
Client
Masseges
Masseges
Masseges
Masseges
Masseges
28
الإرسال غير موقف والاستقبال موقف.
يقوم نظام التشغيل بتخزين المعلومات المرسلة إلى حين استلامها، ولكن عملية التخزين تلغي
الحدود بين الرسائل . أي أن المستخدم والمرسل يتعاملان مع الرسائل على أنها سلسلة من
المحارف، وعملية الإرسال هي إضافة مزيد من المحارف إلى الخزان الذي يقرأ منه المستقبل.
مثال.
6. خلاصة
التزامن بين الإجرائيات هو علاقة تفرضها متطلبا ت المنظومة التي تمثلها الإجرائيات، والتي قد
تحتاج إلى التعاون والتنسيق بين بعضها البعض . ولتحقيق التزامن بين الإجرائيات نحتاج إلى
حل عديد من المشكلات، أهمها مشكلة المقطع الحرج والخصائص المطلوبة منه . وتقدم أنظمة
التشغيل عددًا من الآليات التي تسمح بتمثيل علاق ة التزامن وحل مشكلة المقطع الحرج، وتنقسم
هذه الآليات بشكل عام إلى جزئين : الجزء الأول ويعتمد على الذاكرة المشتركة، ويحوي آليات
السيمافور والمراقب، وهو أكثر شيوعًا في النظم المركزية . ويعتمد الجزء الثاني على تبادل
الرسائل وهو أكثر شيوعًا في الأنظمة الشبكية وا لموزعة حيث لاتوجد ذاكرة مشتركة . وتدعم
أغلب نظم التشغيل كلتا الآليتين تاركة الاختيار لمصمم التطبيقات ليختار الآلية الأنسب.
multicast
anycast
unicast
broadcast
29
نهاية الوحدة
المحاضرة الخامسة:
1
جدولة الإجرائيات
1. مقدمة
تعريف الجدولة
سبق وتكلمنا في الفصل الثالث عن الإجرائيات وحالاتها المخلتفة ، وميزنا حالة الإجرائيات
.Current Process من حالة الإجرائية الحالية أو الراهنة Ready Processes الجاهزة للتنفيذ
والجدولة هي عملية اختيار الإجرائية الراهنة بين الإجرائيات القابلة للتنفيذ . وتنبع أهمية الجدولة
من أثرها الكبير على استخدام الموارد وعلى أداء النظام بشكل عام.
تعريف الإجرائية:
هي سلسلة من التعليمات التي تنفذ ضمن سياق تنفيذي معين يعرف باسم حالة الإجرائية . تتضمن
حالة الإجرائية عددًا من المعلومات مثل:
سجلات
مكدس
مساحة من الذاكرة مخصصة للإجرائية
تمر الإجرائية خلال فترة حياتها بعدة حالات للتنفيذ، ويتضمن مخطط الحالات الأبسط حالتي
تنفيذ:
أي أنها مستحوذة على وحدة المعالجة. :Running الإجرائية تعمل
ولكنها لاتعمل: أي أنها غير مستحوذة على وحدة المعالجة. Ready الإجرائية جاهزة للعمل
كانت أغلب أنظمة التشغيل المألوفة لدى المستخدمين خلال سنوات الثمانينات وبداية التسعينات
لاتحوي على خوارزميات جدولة متطورة. ولم يكن بإمكان نظام التشغيل أن DOS, MacOS
يقوم بتشغيل أكثر من إجرائية واحدة، حتى يطلب منه المستخدم الالتفات إلى إجرائ ية أخرى .
على محطات Unix وقد اقتصر استخدام أنظمة التشغيل القادرة على تحقيق جدولة متطورة مثل
العمل والمخدمات المكلفة جدً ا. ولم تبدأ أنظمة التشغيل للحواسيب الشخصية بالتحول نحو
.WindowsNT خوارزميات جدولة متطورة إلا في منتصف التسعينات مع
بتطورات كبيرة في بنيان الحواسيب والإمكانات المتاحة في WindowsNT وترافق ظهور
الحواسيب الشخصية، إذ اقترب أداء الحواسيب الشخصية العادية المتاحة لدى أغلب المتسخدمين
بشكل ملموس من محطات العمل الأكثر تطورًا، وتجاوز بكثير أداء محطات العمل التي كانت
مستخدمة في التسعينات.
2
ظهرت تغيرات في طبيعة التطبيقات إذ انتشرت التطبيقات التي تعتمد تعدد الإجرائيات وتعدد
النياسب، ولاسيما في ضوء انتشار التطبيقات التفاعلية . إذ بات من غير المقبول بالنسبة
للمستخدم ألا يكون قادرًا على تصفح عدة صفحات للوب والتنقل بين صفحة وأخرى بينما ينتهي
من تحميل الصفحات الب طيئة، وربما يكون قد طلب تنزيل عدة ملفات في نفس الوقت، ويجب أن
تتم هذه الأعمال كلها على التوازي وبدون أن يشعر المستخدم بأن هناك تأخيرًا في واحد منها
بسبب الآخر.
تصنيف الإجرائيات
يتميز سلوك الإجرائيات بأنها تعمل عمومًا على شكل رشقات متناوبة من عمليات المعالج ة
والدخل والخرج . إذ تبدأ الإجرائية بتنفيذ عدد من التعليمات (رشقة معالجة ) تليها رشقة من
عمليات الدخل والخرج، ثم تعود إلى العمل من جديد مستخدمة البيانات التي حصلت عليها من
عمليات الدخل والخرج، وهكذا دواليك. ويمكن تصنيف الإجرائيات إلى نوعين :
إجرائيات محدودة بالدخل والخرج: يكون فيها طول رشقات الدخل والخرج أطول من
رشقات عمليات المعالجة.
إجرائيات محدودة بالمعالجة: وهي إجرائيات تحتوي أساسًا على عدد قليل من رشقات
المعالجة الطويلة، وتكون رشقات الدخل والخرج قليلة وقصيرة.
تؤثر عمليات الدخل والخرج كثيرًا على عملية الج دولة، إذ يقوم المجدول تلقائيًا بسحب المعالج
من أية إجرائية تقوم بإجراء عمليات للدخل والخرج وذلك بسبب طول هذه العمليات . فإذا أخذنا
مثا ً لا قراءة حرف من البوابة التسلسلية، فإن هذه العملية تحتاج إلى فترة زمنية تبلغ حوالي 1
م.ثانية، وهذا الوقت يكفي المعالج للقيام بمئات آلاف التعليمات كحد أدنى.
اشتد التباين بين سرعة المعالجات التي تتزايد باطراد حسب قانون مور ، وبين سرعة دارات
الدخل والخرج التي لم تتغير كثيرً ا. فعلى سبيل المثال تمكنت شركة إنتل من ضرب سرعة
بينما لم تزد سرعة الأقراص الصلبة ،Pentium المعالج بأكثر من 50 منذ بداية إنتاج معالجات
بأكثر من ثلاث إلى خمس مرات خلال الفترة نفسها . وبسبب هذا التباين الكبير، لايجوز أن
يترك المعالج منتظرًا لحين انتهاء عملية الدخل والخرج.
متى يحتاج النظام إلى اتخاذ قرار بشأن إجراء جدولة ؟
عندما تنتقل الإجرائية الراهنة إلى حالة الا نتظار، وهناك أسباب عديدة لذلك، كالحاجة
إلى إجراء عمليات دخل وخرج، أو الانتظار لفترة معينة، أو بسبب المزامنة مع إجرائية
أخرى.
3
عندما تنتقل الإجرائية الراهنة إلى حالة القابلة للتنفيذ، كما يحصل بعد تنفيذ مقاطعة
الميقاتية التي تخبر الإجرائية الراهنة بانتهاء شري حتها الزمنية في نظام تشغيل يعمل بمبدأ
التشارك بالوقت.
عندما تنتقل إجرائية من حالة الانتظار إلى حالة القابلة للتنفيذ، كما يحدث عندما تنتهي
عملية الدخل والخرج التي كانت تقوم بتنفيذها.
2. خوارزميات الجدولة
معايير تقييم الخوارزميات
هناك العديد من المعايير الممكنة:
يجب المحافظة على ارتفاع نسبة استخدام :CPU utilization نسبة استخدام المعالج
المعالج قدر الإمكان، والمقصود بذلك الحد من الفترة التي يقضيها المعالج دون تنفيذ تعليمات
الإجرائيات.
.Throughput زيادة عدد الإجرائيات التي تنهي تنفيذها خلال وحدة الزمن
اختصار زم ن تنفيذ الإجرائية، وهو الزمن الفاصل بين طلب التنفيذ وانتهائه
.Turnaround time
وهو الزمن الفاصل بين تقديم طلب إلى :Response Time اختصار زمن الاستجابة
المعالج والحصول على اول جواب منه.
وهو الزمن الذي تقضيه الإجرائية منتظرة ف ي :Waiting time اختصار زمن الانتظار
رتل الإجرائيات الجاهزة . وهو مقياس أفضل لأداء المجدول من زمن التنفيذ، إذ أن الأخير
يشمل زمن انتظار الدخل والخرج الذي لا علاقة للمجدول به.
وهي نسبة الزمن اللازم لتنفيذ الإجرائية :Penalty time اختصار نسبة التردي
بالمقارنة مع الزمن الذي كانت الإجرائية ستحتاجه في بيئة مثالية.
رفع فاعلية المجدول، وذلك لأن الزمن اللازم للجدولة يمثل كلفة إضافية ومتكررة نظرًا
لتواتر هذه العملية.
FCFS (First-Come, First-Served) خوارزمية الجدولة بحسب ترتيب الوصول
وهي أبسط الخوارزميات : يختار المجدول الإجرائية التي في رأس الرتل، وتدخ ل الإجرائيات
الجديدة الرتل في نهايته . لاتتخلى الإجرائية عن المعالج حتى انتهائها، أو عند قيامها بعمليات
دخل خرج.
4
لنفترض وجود الإجرائيات الأربع التالية مع أزمان التشغيل الموافقة لها :
P3 P2 P الإجرائية 1
3 3 الزمن 24
يكون معايير التقييم على الشكل p1p2p في حال تنفيذ الإجرائيات بحسب الترتيب : 3
التالي:
17 ثانية = (24 + 27) / زمن الانتظار الوسطي : 3
17 ثانية =(30+24+27)/ زمن التنفيذ الوسطي : 3
تدفق الإجرائيات : 6 إجرائيات/دقيقة.
ستكون المع ايير على الشكل p1p3p وفي حال تنفيذ الإجرائيات بحسب الترتيب : 2
التالي:
زمن الانتظار الوسطي : 6 ثانية
زمن التنفيذ الوسطي : 13 ثانية
تدفق الإجرائيات : 6 إجرائيات/دقيقة.
ونستنتج من ذلك أن تغييرًا طفيفًا في الترتيب أدى إلى اختلاف كبير في النتائج من مرتبة
.100%
تعاني هذه الإجرائية من مشكلة أداء في حال وجود تمايز كبير بين الإجرائيات . فلو كانت عندنا
إجرائية محدودة بالمعالجة، ويليها عدد من الإجرائيات المحدودة بالدخل والخرج، ستقضي تلك
الأخيرة معظم وقتها منتظرة انتهاء الإجرائية من المعالج . ولتأكيد هذه النقطة، نأخذ مثا ً لا ثانيًا لا
تصل فيه الإجرائيات في نفس الوقت :
Shortest Job First (SJF) خوارزمية الجدولة بحسب الأقصر أو ً لا
يتلخص مبدأ عمله هذه الخوارزمية في حساب طول رشقة التنفيذ القادمة لكل إجرائية، وتسليم
المعالج للإجرائية ذات أقصر رشقة تنفيذ . وإذا تساوى الزمن لدى إجرائيتين، نأخذ الأولى في
الترتيب الزمني.
إذا طبقنا الخوارزمية على المثال السابق، فإننا نحصل على النتيجة التالية :
P1 P2 P3
P1 P3 P2
5
ويظهر المخطط التالي عملية الجدولة للإجرائيات المذكورة :
لو حسبنا معايير أداء الخوارزمية في هذه الحالة، سنحصل على الجدول التالي :
ونسنتنج من هذا الجدول وجود تباطؤ كبير في الإجرائيات التي يكون زمن تنفيذها
لديها نسبة تباطؤ هي % 3.5 ، ويمكن أن يكون الرقم أسوأ بكثير ،P قصيرًا، فالإجرائية 3
عند وجود إجرائيات طويلة تعيق تنفيذ الإجرائيات التي تليها.
إن هذه الخوارزمية تناسب إذًا الإجرائيات التي يكون زمن تنفيذها طوي ً لا، أي أنها
محدودة بالمعالجة وليس بالدخل والخرج . وهو تمامًا عكس ما يفضل أن تكون عليه
خوارزميات الجدولة، إذ أن أغلب التطبيقات التفاعلية والتي تتعاطي مباشرة مع المستخدم
هي من النوع المحدود بالدخل والخرج.
وربما كانت الميزة الحقيقة الوحيدة في هذه الخوارزمية هي عدم وجود مجاعة، إذ
ستحصل كل إجرائية على المعالج إذا انتظرت دورها.
ونلاحظ هنا انخفاضا كبيرًا في زمن الانتظار وفي نسبة التباطؤ بالمقارنة مع الخوارزمية
الأولى. ويمكن إثبات أن هذه الخوارزمية تعطي زمن الا نتظار الوسطي الأصغر بين كل
خوارزميات الجدولة.
النقطة الأصعب هنا تكمن في حساب طول رشقة التنفيذ . ففي حالة الجدولة بعيدة الأمد، وهي
التي تستخدم في نظام يعمل بمبدأ الدفعات، يطلب من المستخدم إعطاء تصور عن الزمن . وإذا
كانت القيمة المعطاة اقل بكثير من الرقم الحقي قي، يوقف نظام التشغيل عمل الإجرائية . أما في
حالة الجدولة قصيرة الأمد، فنعتمد على أطوال الرشقات السابقة لنتوقع الرشقات القادمة . ويتم
6
استخدام خوارزمية معيارية لحساب وسطي أطوال الرشقات السابقة.
فعلينا ،n هو الطول المتوقع للرشقة Sn و ،n هو الطول المقاس الرشقة رقم Tn فإذا افترضنا أن
قيمته بين الصفر والواحد ونستخدم المعادلة التالية : w اختيار معامل تثقيل
الأهمية النسبية للماضي والحاضر، فإذا كانت القيمة 0.5 ، نكون قد أعطينا أهمية w تحدد قيمة
للرشقة الأخيرة تعادلة سابقاتها، أما إذا كانت 1، فهذا يعني أننا لانهتم إلا بالرشقة الأخيرة.
لدى وصول إجرائية زمن تنفيذ رشقتها أقصر مما تبقى من زمن رشقة الإجرائية الراهنة،
يختلف عمل المجدول في حال إذا كان شفعيًا أو غير شفعي.
شفعي: تستبدل الإجرائية الراهنة ويعطى المعالج للإجرائية الوافدة.
غير شفعي: فسيترك الإجرائية الراهنة تتابع التنفيذ حتى تنهي رشقتها ثم تتخلى طوعًا
Shortest عن المعالج للإجرائية الوافدة. وتعرف الحالة الشفعية باسم
.remaining time first
الجدولة بتقاسم الزمن
هذه الخوارزمية موجهة لمستخدمي الأنظمة التي تعمل بتقاسم الزمن، وهدفها الأساسي هو رفع
درجة التفاعلية للمستخدمين مع النظام وإعطاؤهم الانطباع بأن ك ً لا منهم يمتلك الحاسوب لوحده.
تشبه هذه الخوارزمية تلك التي تعتمد مبدأ الترتيب الزمني، مع الفرق بأن هذه الخوارزمية
وتحصل ،Time Slice تضيف مفهوم التبديل الشفعي. بحيث تخصص لكل إجرائية شريحة زمنية
الإجرائيات على المعالج بحسب ت رتيب وصولها، ولكن لفترة زمنية تعادل الشريحة الزمنية،
للتخلى عن المعالج بعدها وتعود للانتظار في نهاية رتل الإجرائيات الجاهزة.
يحتاج تنفيذ هذه الخوارزمية إلى تفعيل المقاطعات الواردة من الميقاتية، فعندما نقوم بتخصيص
إجرائية بالمعالج، نطلب من الميقاتية أن ترسل مقاطعة بعد انتهاء فترة الشريحة الزمنية.
في هذه الخوارزمية يمكن أن يحصل تبديل السياق إذا لأحد سببين:
) انتهاء الشريحة الزمنية للإجرائية الحالية
) قيام الإجرائية بتنفيذ عملية ينتج عنها توقف مثل طلب دخل/خرج، أو حجز سيمافور.
يظهر الشكل التالي عملية الجدولة بتقاسم الزمن في مثالنا المتكرر، ونفترض أن كافة الإجرائيات
بدأت في نفس الوقت.
Sn+1= wTn+ (1-w)Sn
7
زمن
التنفيذ
زمن
الوصول
الإجرائية
3 0 P1
5 1 P2
2 3 P3
5 9 P4
5 12 P5
تؤدي هذه الخوارزمية إلى تنفيذ عدد كبير من عمليات تبديل السياق، وتبرز هنا ضرورة كون هذا
الزمن أمثليًا وهذا أحد الأسباب الأس اسية للانتقال إلى نموذج النياسب . يقترب أداء الخوارزمية من
كلما أطلنا الشريحة الزمنية. FCFS أداء
الجدولة بالأولوية
تناط بكل إجرائية أولوية ما، ويقوم المجدول بتخصيص المعالج للإجرائية ذات الأولوية الأعلى،
إحدى SJF وفي ح ال تساوي الأولويات يعتمد مبدأ الترتيب الزمني . ويمكن اعتبار خوارزمية
حالات الجدولة بالأولوية بحيث تكون الأولوية هي طول رشقة التنفيذ، وتتغير الأولوية مع الزمن
بفضل خوارزمية حساب الوسطي التي عرضناها.
8
وهي أكثر الحالات ،Static عندما تكون الأولوية رقمًا مثبًا، تعرف هذه الحالة بالأولوية الساكنة
شيوعًا. وتعاني من مشكلة المجاعة، إذ لن تحصل الإجرائيات ذات الأولوية المنخفضة على
المعالج في وقت مقبول.
وفي أنظمة الزمن الحقيقي التي تعتمد كثيرًا على الجدولة بالأولوية، فإن هذا يشكل مشكلة كبيرة
لأنه قد يؤدي إلى تأ خر الإجرائية عن زمنها الحدي وعدم تمكنها من أداء العمل المطلوب في
الوقت اللازم.
لرفع أولوية الإجرائيات الجاهزة Aging تعتمد خوازميات الجدولة بالأولوية على مفهوم التقادم
والتي تبقى منتظرة في الرتل دون الجصول على المعالج . وفي هذه الحالة تقسم الأولوية إلى
جزئين:
جزء ثابت: يحدد لدى إنشاء الإجرائية.
جزء متغير: يتغير بحسب التقادم.
وتكون الأولوية الفعلية للإجرائية هي مجموع الرقمين . ويتم رفع الجزء المتغير لكافة
الإجرائيات المنتظرة في الرتل بعد كل عملية تبديل سياق، ويعاد تأسيس الجزء المتغير بعد
تخصيص الإجرائية المنتظرة بالمعالج.
الجدولة متعددة المستويات
وهي تشبه الجدولة بتقاسم الزمن وتختلف عنها بأنها لاتعتمد على رتل واحد للإجرائيات الجاهزة
وإنما على أرتال عدة، ويدار كل من هذه الأرتال بطريقة مختلفة عن الرتل الآخر . مثال على
ذلك هو الفصل بين الإجرائيات التفاعلية والإ جرائيات غير التفاعلية، ويقوم المجدول بالجدولة
على مستوين:
) المستوى الأول : هو بين الأرتال، إذ يخصص المجدول شريحة زمنية لكل من الأرتال
تتناسب مع طبيعة وعدد الإجرائيات ضمنه، كأن يخصص % 80 من زمن المعالج لصالح
رتل الإجرائيات التفاعلية و% 20 للإجرائيات غير التفاعلية.
) المستوى الثاني : هو داخل كل رتل، بحيث يقوم المجدول بإدارة كل رتل باستخدام
خوارزمية مختلفة تتناسب مع طبيعة الإجرائيات ضمنه . فيدار رتل الإجرائيات التفاعلية
باستخدام خوارزمية تقاسم الزمن، أما رتل الإجرائيات غير التفاعلية فيدار باستخدام
خوارزمية الترتيب الزمني وبدون تبديل شفعي.
9
يمكن أن تسمح الجدولة بنقل الإجرائية من رتل لآخر وذلك لإعطاء الإجرائيات التي تحتاج إلى
الكثير من عمليات الدخل والخرج وهي أقرب إلى التفاعلية، أولوية بالمقارنة مع الإجرائيات
التي تقوم بعمليات حساب كثيفة وغير تفاعلية.
ولتوضيح الفكرة نورد المثال التالي :
يخصص المجدول ثلاثة أرتال للجدولة ارقامها 0 و 1 و 2، ويكون الرتل رقم 0 الأعلى
أولوية. ولاتنفذ الإجرائيات في رتل ما إلا عندما يكون الرتل الأعلى أولوية فارغًا
، تبدأ الإجرائية عملها في الرتل رقم 0
ويخصص لها حصة زمنية مقدارها 8
م.ثا، فإذا استهلكتها كلها د ون القيام
بعمليات دخل /خرج، تنقل إلى الرتل رقم
.1
، عند تنفيذ إجرائية من الرتل رقم 1
تخصص لها حصة زمنية مقدارها 16
م.ثا، فإذا استهلكتها تنقل إلى الرتل رقم 2
يدار الرتل رقم 2 باستخدام خوارزمية
تقاسم الوقت مع حصة زمنية عالية، أو
باستخدام خوارزمية الترتيب الزمني.
10
وسنعطي هنا شرحًا تقريبيًا للخوارزمية : :UNIX مثال آخر الجدولة في نظام
تخصص الإجرائية بأولوية مقدارها 60 لدى بداية عملها حيث الأولوية تابع متناقص.
تولد ميقاتية النظام مقاطعة بدور يتراوح بين 10 و 20 م .ثا، ونفترض أنه سيكون لدي نا
60 مقاطعة في الثانية.
،CPU usage " تحتوي كتلة التحكم بالإجرائية على حقل يدعى "استخدام المعالج
ويضاف 1 إلى هذا الحقل في كل مرة تقاطع فيها الإجرائية.
يختار النظام دومًا الإجرائية ذات الأولوية الأعلى لتخصيصها بالمعالج، وفي حال
وجود تساوي في الأولويات، يختار الإجرائية التي مر عليها زمن أطول.
يقوم نظام التشغيل بتعديل الأولوية واستخدام المعالج دوريًا (مرة في الثانية ) بحسب
الصيغة التالية :
1) استخدام المعالج = استخدام المعالج/ 2
( 2) الأولوية = الأولوية الأساسية + (استخدام المعالج/ 2
أي أن الإجرائية التي لم تستخدم وحدة ا لمعالجة كثيرًا مؤخرًا تحصل على أولوية
أعلى، وبذلك تكون أولوية الإجرائيات التي تكثر من عمليات الدخل والخرج والإجرائيات
التفاعلية أعلى من أولوية الإجرائيات التي تكثر من استخدام وحدة المعالجة . وهو ما يحسن
من زمن استجابة التطبيقات التفاعلية ويعطي الراحة لمستخدمي هذه التطبيقات.
لطيف !!)، ) nice يسمح النظام للمستخدم بتخفيض أولوية إجرائية باستخدام تعليمة
والتي تسمح بزيادة قيمة ثابتة إلى أولوية الإجرائية في كل تعديل دوري لتصبح الصيغة :
الأولوية = الأولوية الأساسية + استخدام المعالج/ 2 + تخفيض الأولوية.
يمكن للمستخدم بذلك تخفيض أولوية الإجرائيات التي لايراها مهمة وذلك لإفادة
الإجرائيات الأخرى (بما فيها تلك الخاصة به).
نهاية الوحدة
المحاضرة الأولى
1مقدمة
الهدف من الفصل
يهدف هذا الفصل إلى تحصيل الأهداف والمعارف التالية:
إعطاء تعريف أولي لنظام التشغيل، يستند إلى الأدوار المختلفة للنظام.
إعطاء لمحة تاريخية عن أنظمة التشغيل وتطورها عبر الزمن.
استعراض الأشكال المختلفة لأنظمة التشغيل المستخدمة مع النقاط المميزة لكل منها.
1. ماهي أنظمة التشغيل؟
تطورت الإجابة على هذا السؤال بشكل ملموس خلال العقود التي تشكل فترة حياة الحاسوب .
ففي الستينات، كانت الإجابة هي "البرمجيات التي تتحكم بالتجهيزات ". أما في يومنا هذا، فهذه
الإجابة غير كافية، إذ تطور استخدام الحاسوب إلى درجة تجعل من الصعب إعطاء إجابة
دقيقة.
ويمكننا في البداية الاحتفاظ بهذا التعريف مع تطويره ليصبح على الشكل التالي:
نظام التشغيل هو مجموعة البرمجيات المسؤولة عن التحكم بعمل الموارد المختلفة في
الحاسوب، وتوزيعها على التطبيقات والمستخدمين بحسب حاجتها.
ونحن في هذا التعريف نبرز إحدى أهم المهام في أنظمة التشغيل : إدارة الموارد وتخصيصها .
وأهم هذه الموارد هي التجهيزات المتوضعة ضمن الحاسوب، من معالجات وذاكرة ووسائط
تخزين وتجهيزات للدخل والخرج وتجهيزات للاتصالات.
2. مهام نظام التشغيل
يهدف التصميم الحالي لأنظمة التشغيل إلى تأدية ثلاث مهام رئيسية:
إخفاء تفاصيل عمل التجهيزات عن المستخدم والتطبيقات:
إذ يشكل نظام التشغيل آلة افتراضية تحصر تعامل التطبيقات مع الموارد الحاسوبية المتختلفة
عبر واجهة برمجية عالية المستوى. وتعتمد في ذلك على الحد من العمليات التي يمكن
للتطبيقات أن تقوم بها مباشرة، وتزويدها عوضًا عن ذلك بعدد من التوابع التي يمكن
. للتطبيقات استدعاؤها ويقوم نظام التشغيل بتنفيذها 1
System calls 1 تسمى هذه الآلية باستدعاءات النظام
إن هذا المستوى العالي من التجريد مفيد جدًا للأسباب التالية:
إن البرمجيات المستخدمة للتحكم بالتجهيزات ليست معيارية بطبيعتها، وهي متنوعة
إلى حد كبير . ومن الصعب التعامل معها بدون وجود مستوى عال من التجريد . ومثال
على ذلك هو تجهيزات الدخل والخرج، التي غالبًا ما يكون التعامل معها عبر عمليات
.Open, Close, Read, Write, IOctl : برمجية يع رفها نظام التشغيل
هناك عدد من المفاهيم المجردة التي لا يوجد ل ها مقابل على مستوى التجهيزات،
ومثال على ذلك هو نظام الملفات الذي يهدف إلى إخفاء تفاصيل التعامل مع أقراص
التخزين والطرق المختلفة لتوضع البيانات ضمن هذه الأقراص عن التطبيقات.
يسمح هذا التجريد بإظهار الحاسوب للبرامج على شكل مجموعة حواسيب افتراضية،
وبحيث ينفذ كل برنامج على حاسوب افتراضي مستقل . ويسمى البرنامج قيد التنفيذ
وهي واحدة التنفيذ التقليدية في أنظمة التشغيل. ،Process بالإجرائية
إن التعامل الإلزامي مع الآلة الافتراضية لنظام التشغيل كطريق وحيد للتعامل مع
التجهيزات يسمح بفرض ضوابط الأمن الضرورية لحماية المس تخدمين وبياناتهم
وإجرائياتهم.
تخصيص الإجرائيات بالموارد التي تحتاجها:
وبذلك يكون نظام التشغيل .Resource Manager وهو دور نظام التشغيل كمدير للموارد
مسؤو ً لا عن حل التضارب في طلب الموارد وإدارتها بالشكل الأمثلي والتأكد من عدم استئثار
. إجرائيات بالموارد على حساب إجرائيات أخرى 2
حيث توزع الموارد ،Time Multiplexing يمكن لإدارة الموارد أن تعتمد مبدأ التوزيع الزمني
على الإجرائيات بالترتيب، كما يحصل عندما يوزع نظام التشغيل زمن المعالج على عدة
إجرائيات، ويقوم بتبديل الإجرائية كلما انقضت مدة زمنية معينة . يمكن أن يكو ن التوزيع أيضًا
بحيث تحصل كل إجرائية على جزء من المورد، كما ،Space Multiplexing بحسب المكان
هو الحال في إدارة الذاكرة التي تقسم إلى أجزاء تحجز لصالح الإجرائيات.
Starvation 2 وهو ما يعرف بالمجاعة
تزويد المستخدمين بواجهة تخاطبية:
تسمح لهم بتوجيه طلباتهم إلى نظام التشغيل بالشكل الأنسب وا لأكثر تلبية لمتطلباتهم . وفي
كثير من الأحيان تكون هذه الواجهة عنصرًا أساسيًا في اختيار المستخدم لنظام التشغيل،
لاسيما في حالة الحواسيب الشخصية . وتحتوي هذه الواجهة التخاطبية على العديد من
المكونات، وأهمها:
تقديم المعونة للمستخدم.
متصفح نظام الملفات.
تزويد التطبيقات البرمجية المختلفة بواجهة
. موحدة تحوي العديد من الوظائف المعيارية 3
3. التطور التاريخي لأنظمة التشغيل
تطور استخدام الحواسيب بشكل حاد خلال الفترة الفاصلة بين بداية استخدامها وعصرنا
الحالي. وكانت قيمة تجهيزات الحاسوب وكلفة صيانته في البداية أكبر بكثي ر من كلفة اليد
العاملة اللازمة لتشغيله واستثماره، ولذلك كان الهدف الأساسي لأنظمة التشغيل في ذلك الحين
هو السماح لأكبر عدد ممكن من المستخدمين والتطبيقات باستخدام موارد الحاسوب في آن
واحد، وذلك بهدف توزيع الكلفة المرتفعة للتجهيزات على أكبر
عدد من الجهات المستفيدة.
أما في الوقت الراهن، فقد انعكست الآية، وصارت كلفة اليد
العاملة لمستثمري الحاسوب أكبر بكثير من ثمنه، ولم تعد كلفة
محطة تشغيل متطورة عالية الأداء تتجاوز الراتب الشهري
للشخص الذي يستخدمها في حال كان ذلك الاستخدام من السوية
الاحترافية. وبناء عليه، فقد بات التوجه الأساسي في أنظمة التشغيل هو المستخدم وضمان
راحته، وتسهيل استخدامه للحاسوب ورفع انتاجيته إلى
أقصى مايمكن.
هناك العديد من الوظائف الموجودة في أنظمة التشغيل
تعود إلى أكثر من ثلاثين سنة خلت، بينما هناك
مفاهيم أخرى لم تظهر إلا خلال السنوات الخمس
الأخيرة. وهي كلها وظائف مهمة وأساسية ولايمكن الاستغناء عنها، ومن المفيد الاطلاع على
3 مثل قوائم الملفات والتحرير
التطور التاريخي لأنظمة التشغيل لفهم هذه الوظائف وسياق ظهورها وأهمية وجودها.
المرحلة الأولى لأنظمة التشغيل (سنوات الخمسينات)
كانت الحواسيب في البداية مكلفة جدًا، وكانت نفقات ص يانتها وتشغيلها هائلة، وكان التعامل
معها يجري باستخدام واجهة تخاطبية نصية يمكن لمستخدم وحيد استخدامها في لحظة ما .
وكان المبرمجون يتعاملون مع الحواسيب
باستخدام آليات من سوية منخفضة جدًا،
كتلقيم البطاقات المثقبة.
وكان الدور الأساسي لما يمكن تسميته
نظام تشغي ل في تلك الفترة هو القيام
بالمهام التالية:
إدارة تجهيزات الدخل والخرج،
ولاسيما كتابة برمجيات القيادة لتلك التجهيزات التي كانت معقدة جدً ا. وأخذت هذه البرمجيات
شكل مكتبة مشحونة في الذاكرة الأساسية بشكل دائم.
تكثيف عدد مستخدمي الحاسوب الذي كان يقضي وقتًا طوي ً لا بدون عمل بينما كان
المبرمجون يقومون بشحن برامجهم . وكتبت لهذا الغرض العديد من البرمجيات التي كانت
مهمتها شحن التطبيقات مسبقًا على قرص صلب أو أشرطة ممغنطة، ومن ثم طلب تشغيلها
بشكل تلقائي ومتتابع.
المرحلة الثانية (الستينات)
ظهرت العديد من النقاط الهام ة نتيجة محاولة تكثيف استخدام الحاسوب وموارده، ومنها العمل
وذلك بهدف استغلال الوقت الضائع .Multiprogramming على تشغيل عدة برامج في آن واحد
الذي تقضيه البرامج في عمليات الدخل والخرج دون أن تستخدم وحدة المعالجة . وكان
التصور الأولي مبنيًا على تقسيم الذاكرة الم ركزية إلى
عدة أجزاء، يحوي ك ً لا منها برنامجًا، ويقوم نظام التشغيل
بالتبديل بينها بهدف إبقاء وحدة المعالجة تعمل باستمرار.
والمقصود بها هي وضع تجهيزات تسمح ،spooling ظهرت أيضًا وظيفة هامة معروفة باسم
بإجراء عمليات دخل وخرج بسرعة مرتفعة (نسبيًا) بين التطبيقا ت وبين تجهيزات الدخل
والخرج البطيئة، وهي وظيفة لاتزال
مستخدمة حتى يومنا هذا. إذ لاتقوم
التطبيقات بطباعة الملفات مباشرة إلى
الطابعة، بل تقوم بتوليد ملف محفوظ على
القرص الصلب وتتابع عملها وكأنها انتهت،
ويقوم نظام التشغيل بمتابعة عملية الطباعة.
وفي سعيها لتكثيف عدد المستخدمين
المتصلين على الحاسوب، أضافت أنظمت
وهي آلية مطورة من تعدد .Time sharing التشغيل آلية شديدة الأهمية هي تقاسم الزمن
البرامج المذكور سابقًا، وتسمح بتزويد كل مشترك يعمل على الحاسب بطرفية مستقلة متصلة
إلى الحاسب . تستخدم هذه الطرفي ة لإدخال الأوامر ومتابعة التنفيذ وقراءة النتائج بشكل تفاعلي
ويقوم نظام التشغيل بالتبديل بين البرامج التي تعمل بسرعة كافية لإعطاء .(Interactive)
المستخدم الانطباع أنه يعمل على الحاسب لوحدة ولايشاركه فيه أحد.
ونتيجة لتقاسم الزمن بين المستخدمين ظهرت الحاجة إل ى حماية التطبيقات التي تعمل في آن
. واحد من بعضها البعض، إذ لايجوز أن يؤثر تطبيق على تطبيق آخر 4
المرحلة الثالثة (الثمانينات)
مع ظهور الدارات والرقاقات المدمجة على نطاق واسع، وبالتحديد المعالجات الصغرية التي
كانت قادرة على تقديم سرعة معالجة تكافئ الحواسيب ا لكبيرة في سنوات السبعينات، دخلت
أنظمة التشغيل مرحلة الحواسيب الشخصية، مع التركيز على تفاعلية المستخدم مع الحاسوب
وحصوله على النتيجة بسرعة مقبولة . وهنا ظهرت مفاهيم جديدة كالجدولة التبديلية التي تهدف
إلى زيادة التفاعلية وعدم السماح لتطبيق ما بالاستئثار بوحدة المعالجة
لفترة طويلة.
4 مع هذه الوظائف المختلفة، بدأت أنظمة التشغيل تأخذ جزءًا من الشكل الذي نعرفه اليوم، وتحولت
بدورها إلى مستهلك لموارد الحاسوب لايستهان به.
ظهرت أيضًا الحاجة إلى تخزين البيانات والبرمجيات اللازمة لعمل المستخدمين وإتاحة
الوصول إليها بشكل مريح كبديل عن البطاقات المثقبة والأشرطة
،(File System) الممغنطة، وأدى هذا إلى ظهور نظام إدارة الملفات
بالإضافة إلى مفهوم خصوصية بيانات المستخدمين وحمياتها من
بعضهم البعض.
وربما كان الحدث الأهم هو بداية ظهور الواجهة التخاطبية مع الثورة التي أطلقتها أجهزة
ماكنتوش من شركة آبل، والتي غيرت بدون أدنى شك من وجه الحوسبة في العالم أجمع .
وباتت دعايات الحواسيب تركز على مدى راحة المستخدم في التعامل مع الحاسوب ورغبته
في الاستمرار بالعمل عليه، وليس على معايير السرعة البحتة التي كانت شائعة قب ً لا.
المرحلة الرابعة (التسعينات وحتى الآن)
أصبحت الحواسيب الشخصية متاحة لكل الناس تقريبًا، ونمت حاجة المستخدمين لتبادل
المعلومات، وظهرت الشبكات كأداة
فعالة وأساسية في هذا التبادل .
واعتبارًا من النصف الثاني من
عقد التسعينات، لم يعد من الممكن
الحديث عن نظام تشغيل لايدعم
الوصل مع شبكة الإنترنت
باعتبارها أكبر مصدر للمعلومات
في العالم . وحمل ذلك في طريقه
العديد من الأفكار التي انعكست
مباشرة على نظام التشغيل، الذي لم يعد مج رد واجهة تسمح بالتخاطب مع تجهيزات
الحاسوب، بل أعيدت هيكلة النظام ليسمح بالتخاطب مع الشبكة والحواسيب والموارد وظهر
والتي غالبًا ما يكون دورها هو تأمين واجهة ،middleware مفهوم البرمجيات الوسيطة
برمجية تخفي تفاصيل الشبكة عن التطبيقات والمبرمجين، وتسمح بكتابة تطبيقات موزعة على
Java Virtual عدة حواسيب، وأحد أشهر هذه البرمجيات الوسيطة هي آلة جافا الافتراضية
.Machine
4. الأشكال المختلفة لأنظمة التشغيل
،WindowXP : لو سألنا مستخدمي الحاسوب عن أنظمة التشغيل التي يعرفونها، لأجاب أغلبهم
ولكن هذه الإجابات لاتمثل إلا الحد الأدنى من أنظمة التشغيل المتاحة فع ً لا ،Linux وربما
والمستخدمة في الكثير من الحالات التي قد لانراها مباشرة.
أنظمة تشغيل الحواسيب العملاقة
لاتزال الحواسيب العملاقة حاضرة بقوة في مراكز البيانات الخاصة بالشركات الكبرى 5، وهي
تتميز بقدرتها الهائلة على ا لتعامل مع كميات كبيرة جدًا من معلومات الدخل والخرج . ومن
الممكن ان تحوي هذه الحواسيب على مئات الأقراص الصلبة وآلاف الجيجا بايت من سعة
التخزين. وتستخدم هذه الحواسيب أيضًا كمخدمات للويب وتطبيقات التجارة الإلكترونية
.B2B وعمليات التبادل التجاري بين الشركات
تتخصص أنظمة التشغيل لهذه الحواسيب في معالجة العديد من البرامج بآن واحد، وهذه
البرامج تستهلك الكثير من عمليات الدخل والخرج.
وتميز عادة بين ثلاثة أنواع من الخدمات:
التي لاتقوم بأي تبادل تفاعلي مع المستخدم : ومثال عليها هي batch خدمات الأعمال
معالجة عمليات المب يعات في سلسلة من المخازن وارتباطها مع حركة المستودعات . وهي
عمليات تحتاج إلى وقت طويل.
وهي عبارة عن عدد كبير من العمليات الصغيرة، :Transaction خدمات المناقلات
كمعالجة الشيكات في مصرف، حيث تكون العمليات بسيطة جدًا ولكن هناك عدد كبير جدًا
منها يقدر بالمئات أو الآلاف في الثانية.
خدمة تقاسم الوقت: التي تسمح لعدة مستخدمين باستثمار الحاسوب في نفس الوقت.
.OS/ وهو وريث للنظام 360 ،OS/ ومن أهم الأمثلة لهذه الأنظمة هو النظام 390
5 لاسيما الشركات المالية والمصارف
أنظمة تشغيل المخدمات
إن كلمة "مخدم" تتضمن تعريفًا وظيفيًا للمخدمات بغض النظر عن حجمها، وإن درجت العادة
ان تكون المخدمات عبارة عن حواسيب كبيرة. والمخدم هو:
حاسوب يقوم بتقديم خدمات للزبائن الذين يرسلون طلباتهم عبر اتصال شبكي، كمخدم
الوب ومخدم البريد الإلكتروني ومخدم الملفات.
.Linux و ،Window 2003 Server ومثال على أنظمة تشغيل المخدمات
أنظمة التشغيل متعددة المعالجات
إن إحدى أكثر الطرق شيوعًا لزيادة سرعة الحواسيب هي وصل عدة وحدات معالجة ضمن
نظام واحد، وغالبًا ما يستخدم ذلك في المخدمات . وبالتالي تكون أنظمة التشغيل التي تتعامل
مع هذه المعالجات المتعددة هي نسخة متخصصة من نظام تشغيل المخدم.
أنظمة تشغيل الحواسيب الشخصية
تركز هذه الأنظمة على تزويد المستخدم بواجهة تخاطبية ملائمة، وهي مستخدمة على نطاق
واسع في التطبيقات المكتبية والنفاذ إلى الإنترنت . ومن أشهر الامثلة نظام ويندوز بنسخه
المختلفة (باستثناء نسخ المخدم )، ونظام ماكينتوش ولينوكس . وهذه الأنظم ة معروفة إلى درجة
أن أغلب المستخدمين قد لايعرفوا غيرها.
أنظمة التشغيل بالزمن الحقيقي
هذه الأنظمة تعتمد على الزمن كعامل أساسي في عملها . فعلى سبيل المثال، يمكن أن تستخدم
هذه الأنظمة في التحكم بالإجرائيات الصناعية حيث يتم جمع معلومات عن عملية الإنتاج
يجب deadlines واستخدامه للتحكم بالآلات في المعمل . وغالبًا ما تكون هناك أزمنة حدية
الالتزام بها.
فإذا أخذنا منظومة التحكم بحركة عربة ضمن سلسلة الإنتاج والذراع التي تنقل العربة، فلو
أفلتت الذراع العربة قبل أو بعد اللحظة المناسبة بفارق زمني يتجاوز حد التسامح ستتعرض
العربة إلى ضرر بالغ . وهنا نتكلم عن منظومة بالزمن الحقيقي القاسي إذ يجب أن ترسل
. المنظمة أوامرها في لحظة معينة، وليس قبل أو بعد هذه اللحظة 6
أنظمة التشغيل المحمولة
وهي المسؤولة عن التحكم بعمل الحواسيب الصغيرة جدًا والأنظمة المحمولة التي لا تعتبر
بالضرورة حو اسيب، كأجهزة التلفزيون والهواتف المحمولة . وغالبًا ما تكون لهذه الأنظمة
نفس متطلبات أنظمة التشغيل بالزمن الحقيقي، ولكن لديها أيضًا ضوابط الحجم والذاكرة
و PalmOS واستهلاك القدرة التي تجعل منها أنظمة خاصة . ومن أهم أنظمة التشغيل هذه
.Windows CE
نهاية الوحدة
6 هناك أيضًا أنظمة الزمن الحقيقي اللينة، والتي يمكن أن تتقبل حصول خطأ من وقت لآخر،
.VxWorks و QNX كأنظمة التحكم بنقل الصوت والصورة. ومن أشهر أنظمة الزمن الحقيقي
المحاضرة الثانية
1
بنى نظم التشغيل
الهدف من الفصل
يهدف هذا الفصل إلى تحصيل الأهداف والمعارف التالية:
التعريف بالخدمات التي تقدمها أنظمة التشغيل للمستخدمين
التعريف باستدعاءات النظام كأداة أساسية لطلب هذه الخدمات
التعريف ببرمجيات النظام كمجموعة أدوات أساسية للمستخدم
مناقشة الطرق المختلفة لتصميم نظام التشغيل
1. خدمات نظام التشغيل
يقدم نظام التشغيل العديد من الخدمات للبرمجيات ومستخدميها، وذلك بهدف مساعدتهم على
استخدام الموارد الحاسوبية بشكل أمثل . وتشمل المجموعة الأولى من الخدمات تلك التي تسمح
للمستخدمين بالتعامل مع المنظومة الحاسوبية.
User Interface المجموعة الاولى: الواجهة التخاطبية
تقدم جميع أنظمة التشغيل واجهة تخاطبية لمستخدميها تسمح لهم بتوجيه الأوامر للنظام والتعامل
(GUI: Graphical User Interface) مع خدماته المختلفة. وقد انتشرت الواجهات التخاطبية البيانية
منذ سنوات التسعينات وتطورت تدريجيًا حتى باتت جزءًا لايتجزأ من نظام التشغيل، لاسيما في
حالة محطات العمل والحواسيب الشخصية.
وتتدرج أهمية الواجهة التخاطبية البيانية في نظام التشغيل من الحالة القصوى حيث يستحيل
القيام بأية عملية بدونها كما هو الحالي في نظام ماكينتوش الذي كان أول من أطلق هذا النوع
من الواجهات، مرورًا بنظام ويندوز بأشكاله المختلفة الذي يعتمد أساسًا على هذه الواجهات
ولكنه يدعم أيضًا الواجهة التقليدية التي تعتمد على الأوامر النصية المتكوبة
ووصو ً لا إلى أنظمة تفصل كليًا بين هذه الواجهة ونظام ،(CLI : Command Line Interface)
التشغيل، وتسمح للمستخدم بأن يتعامل مع النظام ويستخدم كافة خدماته بدون استثناء دون
بأشكاله المختلفة. Unix المرور بالواجهة البيانية، مثل نظام
Program Execution المجموعة الاولى: تنفيذ البرامج
إن الهدف الأساسي للمستخدم من استخدام الحاسوب هو تنفيذ البرامج والتطبيقات التي يحتاج
إليها، كمعالجات النصوص وبرامج الرسم ومعالجة الصورة . ويجب أن يسمح نظام التشغيل
2
التي (Parameters) للمستخدم بتحديد البرنامج الذي يرغب في استخدامه، وتحديد الوسائط
يرغب في تمريرها له، وطلب تنفيذ البرنامج وإيقاف تنفيذه، سواء كان ذلك نتيجة ا نتهاء طبيعي
للبرنامج أو نتيجة انتهاء قسري ناتج عن طلب المستخدم أو خطأ في التنفيذ . ويجب أن يعرف
المستخدم ما هي نتيجة تنفيذ البرنامج وماهو الخطأ في حال وجوده.
I/O Operations المجموعة الاولى: عمليات الدخل والخرج
هذه العمليات هامة جدًا، إذ أنها تسمح للبرنامج ب الاتصال مع العالم الخارجي والحصول على
المعلومات اللازمة لتنفيذها وإظهار النتائج المطلوبة . ومنها قراءة المحارف من لوحة الملامس
أو عبر البوابة التسلسلية أو قراءة البيانات الواردة عن طريق بطاقة الشبكة، أو إرسال معلومات
للطباعة.
File-system manipulation المجموعة الاولى: التعامل مع نظام الملفات
يعتبر نظام الملفات أحد أهم مكونات نظام التشغيل، وذلك لأنه المسؤول الأساسي عن التعامل مع
والتي يتجاوز عمرها عمر البرنامج الذي أنشأها أو قام بتعديلها . ،persistent البيانات الدائمة
ويحتاج المستخدم إلى التمكن من إنشاء الملفات وحذفها، وقراءة محتواها وتعديلها وحفظ هذه
التعديلات. وقد تكون هناك حاجة لتحديد سماحيات الاستخدام وفرض هذه السماحيات على
التطبيقات المختلفة ولاسيما في الأنظمة متعددة المستخدمين.
Communications المجموعة الاولى: الاتصال
تحتاج التطبيقات إلى تأمين الاتصال فيما بينها، سواء إن كانت تعمل على الحاسوب نفسه أو
على حواسيب مختلفة متصلة عن طريق شبكة، كما هو الحال في تطبيقات الإنترنت وتصفح
الوب. ويمكن أن يكون الاتصال عبر ذاكرة مشتركة، أو عن طريق تبادل الرسائل.
Error detection المجموعة الاولى: اكتشاف الأخطاء
يجب أن يكون نظام التشغيل قادرًا باستمرار على اكتشاف الأخطاء التي قد تحصل في الأجزاء
المختلفة من المنظومة الحاسوبية . قد تكون الأخطاء عتادية، كتلك الناتجة عن ارتفاع درجة
حرارة المعالج أو تآكل الأجزاء الداخلية للقرص الصلب أو تعرض الدارات الإلكترونية للغبار .
ويمكن أن تكون الأخطاء برمجية، كتلك الناتجة عن خطأ في عنونة الذاكرة او محاولة فتح ملف
غير موجود . ويجب أن يتخذ نظام التشغيل الخطوات اللازمة لاكتشاف الأخطاء وتشخيصها
وإعلام الشخص المسؤول (عادة يكون هناك مدير للنظام ) عن معالجة هذه الأخطاء وإصلاحها .
وذلك بهدف السماح Debugging وتقدم أنظمة التشغيل عادة خدمة التنفيذ في حالة الاختبار
3
للمبرمجين ومطوري التطبيقات باكتشاف أكبر قدر ممكن من هذه التطبيقات قبل إرسالها
للزبائن.
أما المجموعة الثانية من الخدمات فتهدف إلى زيادة فاعلية استخدام موارد الحاسوب :
المجموعة الثانية: تخصيص الموارد
ويقصد بذلك إدارة الموارد المتاحة والمتنوعة ضمن الحاسوب كزمن المعالج وذاكرة التنفيذ
وبوابات الدخل والخرج . وتتميز هذه الموارد بمحدوديتها مما ينتج عنه استحالة تخصيص كافة
التطبيقات التي تنفذ في نفس الوقت بكل ما تطلب . ولذلك تتسم هذه الخدمة بأهمية خاصة، إذ يقع
على عاتقها إدارة عملية التخصيص للموارد المختلفة وتلافي الأزمات التي يمكن أن تنتج عن
سوء الإدارة.
المجموعة الثانية: المحاسبة
ويقصد بذلك توليد المعلومات اللازمة لمعرفة حجم استهلاك المستخدمين للموارد المختلفة ضمن
المنظومة الحاسوبية.
المجموعة الثانية: الحماية والأمن
وهي خدمات ضرورية بسبب وجود عدة مستخدمين يستخدمون الحاسوب ومواردة في آن واحد .
والهدف هو حماية البرامج التي تنفذ وبيانات المستخدمين من التعديات المقصودة أو غير
المقصودة. وتنقسم بدورها إلى فئتين من الخدمات :
الحماية: ويقصد بها التأكد من أن التعامل مع مكونات النظام العتادية والبرمجية يمر دومًا
عبر آليات تحكم تمنع حصول نتائج غير مرغوبة . فعلى سبيل المثال، في حال السماح
للتطبيقات بالتعامل المباشر مع التجهيزات، يمكن للبرامج إصدار أوامر لدارات التحكم
بالقرص الصلب من شأنها مسح محتواه، وهذا ماكانت تقوم به الف يروسات لفترة طويلة عندما
لم يكن نظام التشغيل يقدم هذه الحمايات . ولاتقتصر أهمية الحماية على التخريب المتعمد، بل
يمكن ان يكون هناك تخريب غير متعمد.
إذ يمكن للمبرمج أن يحاول .C كالذي ينتج عن أخطاء العنونة الشائعة جدًا بين مبرمجي لغة
استخدام مؤشرات غير مؤسسة، وبالتالي تشير إلى مناطق عشوائية من الذاكرة، وفي حال
السماح بتنفيذ هذه العمليات يمكن أن يكتب البرنامج في مساحات الذاكرة الخاصة ببرامج
اخرى أو بنظام التشغيل . وكان هذا النوع من الأخطاء يؤدي عادة في أنظمة التشغيل التي
إلى توقف النظام عن العمل والحاجة إلى إعادة (Win و 95 Win لاتدعم الحماية إلى (مثل 311
الإقلاع.
الأمن: والمقصود بذلك التحقق من هوية المستخدمين الذين يرغبون في استخدام موارد
4
النظام وحصر التعامل مع هذه الموارد بالمستخدمين المخولين بذلك، وقد يتضمن ذلك أيضًا
الاحتفاظ بسجلات الولوج إلى النظام بهدف اكتشاف محاولات الاختراق الفاشلة ومصدرها.
System calls 2. استدعاءات النظام
تشكل هذه الاستدعاءات الطريقة الأساسية لطلب خدمات نظام التشغيل، وهي غالبًا ما تكون
عالية السوية API متاحة للمبرمجين ومطوري التطبيقات على شكر واجهة لبرمجة التطبيقات
ومن أشهر هذه الواجهات البرمجية : .C++ او C ومكتوبة بلغة برمجة مثل
المستخدم في نظام ويندوز Win32
المستخدم في أغلب أنظمة يونيكس وليونكس ونظام تشغيل ماكنتوش POSIX
Mac OSX
.JVM التي تسمح بالتخاطب مع آلة جافا الافتراضية Java الواجهة البرمجية للغة
لاستدعاءات النظام خصوصية هامة، وهي أنه ا في أغلب الأحيان تسمح للإجرائيات بتنفيذ
تعليمات خاصة غير متاحة عادة للبرمجيات . وسبب ذلك هو أن أغلب وحدات المعالجة تعمل
بحالتين :
وتكون فيها كافة التعليمات مسموحة ومستخدمة. :Kernel Mode حالة النواة
التي تكون فيها تعليمات الدخل والخرج والتعامل مع :User Mode حالة المستخدم
بعض السجلات الحرجة غير مسموحة.
وقد جرى اعتماد هاتين الحالتين بهدف تحقيق الحماية التي تكلمنا عنها في المقطع، وتشكل
استدعاءات النظام عادة نقطة عبور بين هاتين الحالتين.
الحماية: ويقصد بها التأكد من أن التعامل مع مكونات النظام العتادية والبرمجي ة يمر دومًا عبر
آليات تحكم تمنع حصول نتائج غير مرغوبة . فعلى سبيل المثال، في حال السماح للتطبيقات
بالتعامل المباشر مع التجهيزات، يمكن للبرامج إصدار أوامر لدارات التحكم بالقرص الصلب من
شأنها مسح محتواه، وهذا ماكانت تقوم به الفيروسات لفترة طويلة عندما لم يكن نظام التشغيل
يقدم هذه الحمايات . ولاتقتصر أهمية الحماية على التخريب المتعمد، بل يمكن ان يكون هناك
تخريب غير متعمد.
تصنف استدعاءات النظام بحسب الفئات التالية:
التحكم بالإجرائيات، والمقصود بذلك كافة العمليات المتعلقة بتنفيذ البرامج.
إدارة الملفات.
5
إدارة التجهيزات.
إدارة البيانات.
الاتصالات.
ReadFile ويظهر المثال التالي شكل أحد التوابع من واجهة برمجة نظام ويندوز وهو التابع
المستخدم في قراءة بيانات من ملف مفتوح :
BOOL ReadFile(
HANDLE hFile,1
LPVOID lpBuffer,2
DWORD nNumberOfBytesToRead,3
LPDWORD lpNumberOfBytesRead,4
LPOVERLAPPED lpOverlapped5
);
انقر على كل من الكلمات الملونة ضمن السطور البرمجية لترى التوضيح.
إذ تسمح للمبرمجين بكتابة استدعاءات النظام وكأنهم API إن الواجهة البرمجية للنظام مفيدة جدًا
عاديًا، وبدون أن يعرفوا تفا صيل تنفيذ هذه الاستدعاءات، ولو لم Procedure يستدعون إجرا ء
تكن هذه الواجهة موجودة، لكان على المبرمج أن يلم بتفاصيل عديدة، مثل رقم الاستدعاء،
والسجلات المستخدمة لحفظ الوسائط . وغالبًا ما تقدم هذه الواجهة على شكل مكتبة برمجيات
بالإضافة إلى مكتبات التنفيذ اللازمة. ،Compiler ملحقة بالمترجم
المذكور أعلاه 6. ونلاحظ العبور ReadFile ويظهر الشكل آلية استدعاء وتنفيذ استدعاء النظام
بين حالتي التنفيذ المستخدم والنواة بفضل استخدام استدعاء النظام.
الملف الذي نريد القراءة منه : file 1
خزان يستخدم في حفظ البيانات التي ستقرأ من الملف : lpBuffer 2
عدد المحارف المطلوب قراءتها : nNumberOfBytesToRead 3
عدد المحارف المطلوب التي تمت قراءتها فعليًا. :lpNumberOfBytesRead 4
معلومات تستخدم فقط في حال كون قراءة الملف غير متزامنة، أي أن التابع : lpOverlapped 5
ينهى عمله ويعيد النتيجة دون أن ينتهي بالضرورة من قراءة كل المحارف المطلوبة. ReadFile
6 BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
6
لاستدعاءات النظام خصوصية هامة، وهي أنها في أغلب الأحيان تسمح للإجرائيات بتنفيذ
تعليمات خاصة غير متا حة عادة للبرمجيات . وسبب ذلك هو أن أغلب وحدات المعالجة تعمل
بحالتين :
وتكون فيها كافة التعليمات مسموحة ومستخدمة. :Kernel Mode حالة النواة
التي تكون فيها تعليمات الدخل والخرج والتعامل مع :User Mode حالة المستخدم
بعض السجلات الحرجة غير مسموحة.
تختلف أنظمة التشغيل بين بعضها البعض في طريقة تمرير الوسائط لاستدعاءات النظام، وتوجد
حاليًا ثلاث آليات مختلفة لتمرير الوسائط :
استخدام السجلات لتمرير الوسائط، وهذه الطريقة هي الأبسط
تخزين السجلات ضمن مساحة معينة في الذاكرة، وتمرير عنوان هذه المساحة كوسيط .
.Linux و Solaris هذه الطريقة هي المعتمدة في نظامي
استخدام المكدس لتمرير الوسائط، مثل أي استدعاء لإجراء عادي، بحيث يقوم البرنامج
المستدعي بوضع الوسائط على المكدس ويقوم نظام التشغيل بسحبها من المكدس.
ورغم كون الطريقة الأولى الأبسط، فإن ها غير ملائمة بسبب محدو دية عدد السجلات، أما
7
الطريقتان الثانية والثالثة فلاتفرضان حدودًا على عدد الوسائط التي يمكن استخدامها . ويظهر
الشكل التالي آلية عمل الطريقة الثانية:
3. برمجيات النظام
يتكون رأي المستخدم في النظام الذي يتعامل معه عادة عبر استخدامه لبرمجيات النظام، وليس
عبر معرفته لاستدعاءات النظام التي لايتعامل معها إلا قلة من المبرمجين . ويمكن تصنيف هذه
البرمجيات ضمن الفئات التالية :
التعامل مع الملفات : وهي البرمجيات المسؤولة عن إجراء العمليات الأساسية الخاصة
بالملفات، من إنشاء وحذف ونسخ وإعادة تسمية واستعراض وطباعة محتوى بالإضافة
،Windows في نظام Explorer إلى التعامل مع المجلدات . ومثال عليها برنامج المتصفح
.Unix في نظام shell والتعليمات الخاصة بالملفات التي يوفرها مفسر الأوامر
حالة النظام : وهي البرمجيات المسؤولة عن تقديم المعلومات الخاصة بحالة النظام
كالوقت المنقضي منذ الإ قلاع، وحجم الذاكرة المتاح، وعدد المستخدمين الذي يعملون في
لحظة ما، وعدد البرامج التي تنفذ، ونسبة استخدام وحدة المعالجة، وبعض هذه البرامج
تقدم عرضًا مفص ً لا لمعلومات الأداء.
تحرير وتعديل الملفات : وهي البرمجيات المسؤولة عن تحرير الملفات والتعامل مع
التي grep وأداة ،Unix المستخدم في نظام vi محتواها، م ثل محرر النصوص الشهير
تسمح بإجراء عمليات البحث عن نص ضمن الملف.
8
أدوات البرمجة والاختبار : ويقصد بذلك كافة الأدوات اللازمة لتحويل البرامج من حالة
لغة المصدر إلى لغة الآلة . كالمترجمات, وبرمجيات الربط، وبرمجيات التحقق من
والتي تستخدم سواء على مستوى لغة البرمجة أو لغة الآلة . ،debuggers التنفيذ
وتتضمن هذه البرمجيات عادة المكتبات التي تسمح بكتابة استدعاءات النظام بسهولة.
الاتصالات: وهي البرمجيات التي تسمح بتبادل المعلومات بين البرامج التي تنفذ، كأن
يقوم المستخدم بإرسال رسا لة تظهر على شاشة مستخدم آخر . ويتجاوز مدى عمل هذه
البرمجيات الحاسب الواحد، فهي مسؤولة أيضًا عن الخدمات الشبكية، كإرسال البريد
.FTP الإلكتروني، وتصفح الوب، وسحب ملف من مخدم
4. التصميم العام لنظام التشغيل
لايوجد في الحقيقة وصفة جاهزة أو تصميم موحد لأنظمة الت شغيل، ولكن هناك عدد من القواعد
العامة للتصميم تكونت عبر الزمن، ويمكن القول أن تطبيق هذه القواعد يزيد من فرص الوصول
إلى نتائج جيدة إلى حد كبير . والقاعدة الأساسية هي البدء بتحديد المتطلبات، التي يمكن تقسيمها
إلى فئتين:
متطلبات المستخدمين : يجب أن تكون أنظمة ا لتشغيل سهلة الاستخدام والتعلم، عالية
الوثوقية، آمنة وسريعة.
متطلبات النظام : يجب أن تكون الأنظمة سهلة التصميم، والتحقيق والصيانة، بالإضافة
إلى تحقيق شروط المرونة والوثوقية والخلو من الأخطاء والفاعلية.
غالبا ما يتبع تصميم نظام التشغيل مبدأ الطبقات، بحيث تقد م كل طبقة عددًا من الخدمات للطبقة
التي تعلوها، وتستفيد بدورها من خدمات الطبقة الأدنى . وبحسب هذا المبدأ، تكون الطبقة الدنيا
والطبقة العليا هي طبقة واجهة التخاطب مع ،Hardware هي طبقة التجهيزات أو العتاديات
المستخدم.
ويظهر الجدول التالي ترتيب
،THE الطبقات في نظام التشغيل
وهو نظام تشغيل تجريبي بني في
عام 1968 ، ويتكون من ستة
طبقات مرقمة من الصفر حتى
الخمسة.
9
السوية الأولى (رقم صفر ): مسؤولة عن إدارة توزيع وحدة المعالجة والتبديل بين الإجرائيات
عند حصول مقاطعة زمنية . وبذلك كان بإمكان السويات التي فوقها أن تتعامل مع النظام على
أنه مكون من عدد من الإجرائيات التي تعمل بآن واحد.
السوية الثانية : مسؤولة عن إدارة الذاكرة، فقد كانت تقوم بتخصيصي الذاكرة للإجرائيات ضمن
الذاكرة المركزية، بالإضافة إلى ذاكرة تخزين من 512 ألف كلمة كانت تستخدم لحفظ أجزاء
الإجرائيات التي ليس لها مكا ن في الذاكرة المركزية . وبنتيجة ذلك، لم تكن الإجرائيات فوق
السوية رقم 1 تحتاج إلى التفكير إذا كانت مخزنة في الذاكرة المركزية أو ذاكرة التخزين.
السوية الثالثة والرابعة : مسؤولة عن معالجة الاتصالات بين كل إجرائية وشاشة المشغل، بحيث
كانت تعتقد كل إجرائية تعمل فوق هذه الطبقة بأن لديها شاشة إظهار خاصة بها.
السوية الخامسة : هي السوية التي تعمل ضمنها برمجيات المستخدمين وتستخدم خدمات
الإجرائيات والذاكرة والشاشة المقدمة من قبل السويات الأدنى.
السوية السادسة: تحوي على إجرائية مشغل النظام.
.Unix مثال( 1): نظام التشغيل يونيكس
كان نظام التشغيل يونيكس مسيطرًا على سوق محطات العمل والمخدمات طوال فترة الثمانينات
وحتى منتصف التسعينات . وذلك بوصفه نظامًا عالي الوثوقية، متعدد المهام ومتعدد
المستخدمين، ولم يكن له فعليًا أي منافس خلال هذه الفترة . وقد كان البنيان الأساسي لنظام
يونيكس محدودًا بجزئين فقط كما يظهر في الشكل التالي : (انقر على الصورة المجاورة لترى
النسخة المكبرة)
10
.Unix مثال: نظام التشغيل يونيكس
برمجيات النظام : وهي برمجيات تعمل في سوية المستخدم 7، وتضم الواجهة التخاطبية بأشكالها
المختلفة (بيانية، نصية )، بالإضافة إلى أدوات ال برمجة والتطوير ومحرر النصوص وأدوات
معالجة الملفات.
نواة النظام : وهي الطبقة التي تعلو التجهيزات مباشرة ومسؤولة عن تحقيق عدد كبير جدًا من
الوظائف. كإدارة الإجراءات وجدولة المعالج، وإدارة الذاكرة وإدارة الملفات . أي أن نواة النظام
تشكل كتلة كبيرة من البرمجيات المدمجة في طبقة واحدة . مماكان يزيد بشكل ملموس من
صعوبة عمليات الفحص والاختبار لصحة أداء هذه النواة وخلوها من أخطاء البرمجة . وتنفذ هذه
النواة في سوية النواة 8، وتحتاج الإجراءات من أجل العبور من مستوى البرمجيات إلى مستوى
النظام إلى استخدام استدعاءات النظام.
.MicroKernel مثال( 2): النواة المصغرة للنظام
نظرًا للصعوبة البالغة التي كان يمثلها تطوير نظام يونيكس بسبب ضخامة النواة واحتوائها على
عدد كبير من الوظائف في آن واحد، فقد ظهر في نهاية الثمانينات توجه نحو الاعتماد على
كأساس لتطوير نظم التشغيل المستقبلية. ويعتمد ،Micro Kernel مفهوم النواة المصغرة للنظام أو
التصميم الجديد على تقسيم النواة إلى سويتين :
نواة مصغرة : تحوي الأجزاء التي تحتاج إلى التعامل المباشر مع التجهيزات، كإدارة
الإجرائيات وجدولة المعالج، والسواقات البرمجية للتجهبزات . وهذه النواة المصغرة تعمل في
سوية النواة تمامًا مثل النواة السابقة لنظام يونيكس.
أخرجت العديد من وظائف النواة السابقة إلى مستوى التطبيقات: مثل نظام إدارة الملفات. هذه
الوظائف مبنية على شكل كتل تتصل بين بعضها البعض عن طريق تبادل الرسائل.
ويظهر الشكل التالي البنيان العام للأنظمة التي تعتمد النواة المصغرة :
التي تكون فيها تعليمات الدخل والخرج والتعامل مع بعض السجلات الحرجة :User Mode 7 حالة المستخدم
غير مسموحة.
وتكون فيها كافة التعليمات مسموحة ومستخدمة :Kernel Mode 8 حالة النواة
11
ملاحظة.
فإذا أرادت إجرائية ما قراءة معلومات من ملف، تقوم بإرسال طلب إلى إجرائية أخرى مسؤولة
ويقتصر دور .File server عن تنفيذ كافة الطلبات المتعلقة بالملفات وتعرف باسم مخدم الملفات
النواة في هذه الحالة على تمري ر الرسالة بين الإجرائي ة الطالبة، وتعرف أيضًا باسم إجرائية
وإجرائية المخدم. Client process الزبون
ويتكون النظام من عديد من إجرائيات المخدمات كمخدم الذاكرة ومخدم الشاشات ومخدم
الاتصال الشبكي، إلخ.
نتيجة لإخراج العديد من الوظائف خارج النواة، فإن هذا التصميم يتميز بالعديد من المزايا:
سهولة توسيع النواة: إذ أصبحت النواة الجديدة أصغر حجمًا وأكثر تخصصًا، مما يسهل
تطويرها إلى حد كبير.
من السهل استبدال الوظائف وترقيتها، مثل إضافة نوع جديد من الملفات إلى النظام، دون
الحاجة إلى إعادة توليد النواة واختبارها من جديد. لا بل من الممكن أن يتم ذلك دون الحاجة إلى
إيقاف النظام، إذ يكفي إيقاف إجرائية المخدم التي تحتاج إلى ترقية.
نتيجة لإخراج العديد من الوظائف خارج النواة، فإن هذا التصميم يتميز بالعديد من المزايا:
سهولة دعم تجهيزات جديدة: ولاسيما المعالجات، إذ أن الجزء الذي يتعامل مباشرة مع
التجهيزات بات محدودًا وواضحًا.
ازدادت الوثوقية إلى حد كبير: إذ أن حجم البرامج التي تعمل في مستوى النواة وتتعامل
مباشرة مع التجهيزات محدود جدًا بالمقارنة مع السابق. فإذا كان نظام الملفات يحتوي على خطأ
برمجي، فإن الخطأ لن يتنج عنه إلا توقف مخدم الملفات وليس توقف النظام بأكمله كما كان
يحدث سابقًا.
لقد لاقت هذه الفكرة ممانعة كبيرة في البداية بسبب التحدي الذي كان يمثله انخفاض الأداء الناتج
عن تقسيم النواة إلى عدة إجرائية والكلفة المتمثلة في توليد ونسخ الرسائل وزيادة عمليات التبديل
بين الإجرائيات.
ولكن النتائج الإيجابية كانت أكبر بما لايقاس من ذلك الانخفاض، و تعتمد أغلب أنظمة التشغيل
الحديثة بشكل أو بآخر على تصميم مشتق من مبدأ النواة المصغرة.
نهاية الوحدة
المحاضرة الثالثة:
1
الإجرائيات
1. تعريف
تعريف الإجرائية:
هي سلسلة من التعليمات التي تنفذ ضمن سياق تنفيذي معين يعرف باسم حالة الإجرائية.
تتضمن حالة الإجرائية عددًا من المعلومات مثل:
سجلات
مكدس
مساحة من الذاكرة مخصصة للإجرائية: متحولات عامة والذاكرة المخصص ديناميكيًا.
ويظهر الشكل التالي مساحة الذاكرة المخصصة للإجرائية :
ويمكننا أن نميز ضمن الشكل أربعة أجزاء للذاكرة المستخدمة:
يحوي التعليمات بلغة الآلة التي تقوم الإجرائية بتنفيذها :Text 1) الجزء الأول
مخصص لتخزين متحولات الإجرائية. وهو مقسوم بدوره إلى جزئين: :Data 2) الجزء الثاني
المتحولات الساكنة التي لايتغير حجمها: وعمر هذه المتحولات من عمر الإجرائية.
المتحولات الديناميكية: وهي متنوعة المنشأ وتخزن في موقعين مختلفين من الذاكرة:
0
MAX
Text
static data
heap
stack
Free
Memory
2
.Stack المكدس
في مكان خاص يعرف باسم المكدس Procedures تخزن المتحولات الخاصة بالإجراءات
ويتحرك بشكل متناقص، وعمر هذه المتحولات هو مساوٍ لعمر الإجراءات التي أنِشأتها . إذ بعد
انتهاء تنفيذ الإجراء يعود المكدس إلى وضعه قبل التنفيذ، وتختفي بالتالي المتحولات التي كانت
مخزنة عليه.
.Heap الكومة
المتحولات التي تحتاج إلى فترة تخزين تتجاوز عمر الإجرائي ة، مثل المؤشرات والأغراض،
والتي تتحرك بشكل متزايد. ،Heap فهي تخزن على الكومة
ولايجوز أثناء التنفيذ أن يتقاطع المكدس مع الكومة وإلا نتج عن ذلك تدمير للذاكرة وخطأ في
التنفيذ.
2. خصائص هامة للإجرائية
تعتبر الإجرائية واحدة التنفيذ : بمعنى أنه لايمكن أن تنفذ تع ليمتان من نفس الإجرائية بآن
واحد وإنما يجب أن تنفذا بالتتالي واحدة تلو الأخرى.
تعتبر الإجرائية واحدة تخصيص الموارد : أي أن نظام التشغيل يخصص الموارد المختلفة
كزمن المعالج والذاكرة والملفات للإجرائيات.
تكون الإجرائيات معزولة عن بعضها البعض : بحيث لايمكن لإجرا ئية أن تغير مباشرة من
حالة إجرائية أخرى، وبالتالي لايمكن لخطأ في برمجة تطبيق أن يؤثر على عمل تطبيقات
أخرى.
ونورد فيما يلي بعض الأمثلة عن إجرائيات مألوفة لدى العديد من المستخدمين:
الذي يقوم بقراءة وتنفيذ التعليمات التي يطلبها الم ستخدم Unix في نظام shell برنامج
بشكل تفاعلي.
عندما نطلب تنفيذ أي برنامج، يقوم نظام التشغيل عادة بإنشاء إجرائية وتكليفها بتنفيذ
البرنامج.
متصفح الوب هو إجرائية مستقلة.
3
3. حالات تنفيذ الإجرائية
تمر الإجرائية خلال فترة حياتها بعدة حالات للتنفيذ، ويتضمن مخطط الحالات الأبسط حالتي
تنفيذ:
أي أنها مستحوذة على وحدة المعالجة. :Running الإجرائية تعمل
ولكنها لاتعمل : أي أنها غير مستحوذة على وحدة Ready الإجرائية جاهزة للعمل
المعالجة.
ومن البديهي أنه في حالة نظام تشغيل يعمل على حاسوب وحيد المعالج، فستكون لدينا إجرائية
وعديد من ،Current Process واحدة على الأكثر تعمل، تدعى الإجرائية الحالية أو الراهنة
الإجرائيات التي لاتعمل . وتنتظر الإجرائيات التي لاتعمل دورها للحصول على المعالج مرتبة
في رتل انتظار، ويقوم نظام التشغيل بانتقاء الإجرائية التي تعمل من بين الإجرائيات في رتل
الانتظار.
ويظهر الشكل التالي مخطط الحالات مع التنقل بينها:
Ready
Dispatch
Running
Pause
Enter Exit
هذا المخطط مبسط إلى درجة مبالغ فيها، إذ يترك نقطة هامة جدًا بدون أية معالجة:
؟ ماذا تفعل الإجرائية عندما تتوقف مؤقتًا عن العمل منتظرة جصول حدث ما 1
إذ يفرض علينا هذا المخطط أن تبقى الإجرائي ة تستهلك وقت المعالج وتدور في حلقة مفرغة
حتى انتفاء سبب الانتظار . وهذا يعني أننا بكل بساطة نهدر أثمن موارد الحاسوب على
الإطلاق، وهو زمن وحدة المعالجة.
Cat–n testfile | more :UNIX لمزيد من التوضيح، نأخذ المثال التالي من نظام
يظهر المثال إجرائية أولى تقوم ب توليد أسطر مرقمة من
ملف، وترسل هذه الإجرائية خرجها إلى إجرائية ثانية
تقوم بعرض النتيجة مقطعة على الشاشة بحيث يمكن
تصفحها. من المؤكد أن الإجرائية الثانية لايمكنها أن
1 كقراءة عدد من المحارف؟
4
تقوم بشيء مالم تسلمها الإجرائية الأولى البيانات المطلوب عرضها . وفي انتظار هذه البيانات،
يجب أن توقف الإجرائية عن العمل وتوضع في حالة انتظار.
وتوضع الإجرائية في هذه الحالة ،waiting نقوم إذا بتعريف حالة جديدة، وهي حالة الانتظار
عند انتظارها لحدث ما . ويصبح مخطط الحالات على الشكل الجانبي (انقر عليه لتحصل على
النسخة المكبرة).
وباعتبار أنه لايجوز إعطا ء المعالج لإجرائية غير قادرة على الاستفادة منه، فإنه من المفيد ألا
نضع الإجرائيات التي هي في حالة الانتظار في نفس الرتل الخاص بالإجرائيات الجاهزة،
كمايظهر الشكل التالي:
Dispatch CPU
Ready Queue
Event Waiting Queue
occurs
Admit
Event wait
Timeout
وفي بعض أنظمة التشغيل ، يخصص عدد من أرتال الانتظار بحسب نوع الحدث الذي تنتظره
الإجرائية، وذلك بهدف تسريع عملية البحث.
إن كافة الإجرائيات تقوم بعدد كبير من عمليات الدخل والخرج خلال حياتها، وباعتبار أن الفرق
بين سرعة وحدة المعالجة وسرعة وحدات الدخل والخرج كبير جداً وهو في تزايد مطرد، فإن
أغلب الإجرائيات التي تعمل في نظام التشغيل تكون معلقة بانتظار انتهاء عمليات الدخل
والخرج.
5
من الممكن اللجوء نقل بعض هذه الإجرائيات خارج الذاكرة الرئيسية وتخزينها في ذاكرة
التخزين للحاسوب بهدف توفير الذاكرة الرئيسية لتتسع لعدد أكبر من الإجرائية ال جاهزة للعمل .
،suspended ونعرف إذا حالة جديدة هي حالة التعليق
وتنتج عن نقل إجرائية في حالة الإنتظار بعيدًا عن
الذاكرة المركزية.
يجب التمييز بين الإجرائيات المعلقة وتلك التي تكون
في حالة تعليق وينتفي سبب انتظارها، وصلت
المحارف التي كانت تنتظرها مث ً لا، ونحتاج لذلك إلى حالتين جديتين في مخطط الحالات . في
هذه الحالة يجب إعادة الإجرائية إلى الذاكرة المركزية ولكن قد لايتاح ذلك فورًا، ولهذا نحتاج
وذلك موضح في الشكل .suspended-ready و Suspended-waiting : إلى التمييز بين الحالتين
الجانبي.
4. الأنظمة متعددة الإجرائيات
في بداية عمر أنظمة التشغيل، لم يكن بإمكان هذه الأنظمة تنفيذ أكثر من إجرائية واحدة، وأحد
ومشكلة هذه الأنظمة هي في كونها قاصرة عن تلبية متطلبات .DOS أهم الأمثلة عليها هو نظام
المستخدم الذي يحتاج إلى تنفيذ أكثر من عمل في آن واحد (مثال: تحميل ملف على موقع
إنترنت بينما يقوم المستخدم بتحرير نص).
DOS واعتمدت هذه الأنطمة على آليات معقدة بعض الشيء لتلبية هذه المتطلبات، مثل نظام
وهي برمجيات ،TSR: Terminate And Stay Resident الذي كان يستخدم برمجيات من نوع
تبقى دومًا في الذاكرة الرئيسية بعد انتهائها من التنفيذ، ويستدعي ها نظام التشغيل بشكل غير
متزامن. ولكنها ظلت تعاني من مشكلات عديدة كانعدام العزل بينها . إذ كان بإمكان البرنامج أن
يكتب عن طريق الخطأ في الذاكرة المخصصة لبرنامج آخر، مما كان يتنج عنه العديد من
6
الأعطال غير المقبولة.
كافة أنظمة التشغيل الحالية هي من النوع المت عدد الإجرائيات، أي بإمكانها تنفيذ أكثر من إجرائية
وهناك أشكال مختلفة للأنظمة .Windows ونظام Unix واحدة، وأهم هذه الأمثلة هو نظام
متعددة الإجرائيات سنراها لاحقًا وهي غالبًا ما تكون مصممة بحيث تلائم حاجات شريحة معينة
من التطبيقات أو المستخدمين (مثل أنظمة الزمن الحقيقي أو أنظمة تقاسم الوقت).
إحدى أهم المشكلات التي تعاني منها الأنظمة متعددة الإجرائيات هي مشكلة تقاسم الموارد
وتنظيم طلبات الإجرائيات للموارد وحجزها . إذ يبقي سؤال اختيار الإجرائية التي يحق لها
استخدام موارد الحاسوب مطروحًا باستمرار، وأهم تلك الموار د على الإطلاق هو زمن المعالج .
والحل التقليدي هو آلية تعدد الإجرائيات التبديلي، إذ يقوم نظام التشغيل بإعطاء المعالج لإجرائية
ما ولفترة معينة يقوم بعدها بسحب المعالج من هذه الإجرائية وإعطائه لإجرائية أخرى.
نتكلم هنا عن الحالة التقليدية، وهي حالة الحاسوب وحيد المعالج، حيث يعرف تنفيذ عدة
وذلك للتمييز بينه وبين التنفيذ في بيئة متعددة ،concurrency إجرائيات في آن واحد بالتوارد
.parallel المعالجات حيث يكون التنفيذ تفرعيًا
ويطرح تحقيق التوارد العديد من الأسئلة التي تحتاج إلى إجابة:
ما هو معيار اختيار الإجرائية التي ستحصل على المعالج
ما هو السبب الذي يطلب من أجله نظام التشغيل من الإجرائية التي تعمل التخلي عن
المعالج
كيف سيتم حفظ واسترجاع حالة الإجرائية عند تبديل المعالج بين الإجرائيات
ماهي الاحتياطات المتخذة لضمان العدل بين الإجرائيات في توزيع زمن المعالج
تعريفات أساسية
تعتمد أنظمة التشغيل في معظم أعمالها على الاستجابة للأحداث، إذ تنتظر وقوع حدث، ومن ثم
تعالج الحدث لدى حصوله، لتعود بعدها إلى اتنظار حدث جديد . وتعتمد في ذلك على التبديل بين
الإجرائيات المختلفة التي تقوم كل منها بمهمة محددة، ونورد فيمايلي بعض الأمثلة على الأحداث
التي تؤدي إلى حصول تبديل بين الإجرائيات:
عندما يضغط المستخدم على أحد أزرار لوحة المفاتيح، يظهر الحرف المطلوب على
الشاشة.
تطلب إحدى الإجرائيات فتح أحد الملفات وذلك عبر استدعاء إحدى خدمات نظام
التشغيل. فيقوم النظام بالبحث عن أجزاء القرص الصلب التي يج ب نسخها ضمن
7
الذاكرة الرئيسية، ويرسل الأمر اللازم إلى وحدة التحكم بالقرص الصلب للقيام بذلك.
عند انتهاء وحدة التحكم بالقرص الصلب من قراءة الأجزاء المطلوبة تقوم بتوليد
للمعالج . ويقوم نظام التشغيل أثناء معالجته للمقاطعة بتسليم Interrupt مقاطعة
المعطيات المقروءة للإجرائية التي طلبتها ويطلب منها متابعة العمل.
يطلب متصفح الإنترنت إحضار صفحة، وبناء عليه يقوم نظام التشغيل بتوليد الرزم
الواجب إرسالها عبر الشبكة إلى المخدم المطلوب، ومن ثم يقوم بإرسالها، وتتوقف
.(waiting الإجرائية عن العمل منتظرة الجوات (حالة
يرد جواب من مخدم الوب على شكل رزم تحتوي المعلومات المطلوبة، وينتج عن
ذلك مقاطعة للمعالج . ويقوم نظام التشغيل بمعالجة المقاطعة لتحديد الإجرائية التي
يجب أن تستلم الرزم ويقوم بتوجيهها إليها.
عند انتهاء الحصة الزمنية للإجرائية، يجب على نظام التشغيل أن يقوم بحفظ حالة
الإجرائية التي تمتلك المعالج، واختيار إجرائية أخرى ليقوم بتسليمها المعالج
واسترجاع حالتها المحفوظة سابقًا وشحنها ضمن المعالج.
يمكننا هنا التعرف على عمليتين أساسيتين نقوم بتعريفهما فيما يلي:
تسمى عملية انتخاب الإجرائية التي يتم تخصيصها بالمعالج :scheduling الجدولة
وهي عملية فائقة الأهمية وسنفرد لها فص ً لا خاصًا. ،scheduling بالجدولة
تسمى مجموعة المعلومات التي يستخدمها نظام :Process context سياق الاجرائية
وتسمى عملية حفظ .Process context التشغيل لتحديد حالة الإجرائية بسياق الاجرائية
حالة الإجرائية التي تمتلك المعالج واسترجاع حالة الإجرائية التي ستحل محلها بتبديل
ويعتبر تبديل السياق أحد أهم العمليات التي يقوم بها نظام .context switching السياق
التشغيل، لاسيما وأنها تتكرر بتواتر كبير جدًا.
سؤال: كيف يحقق نظام التشغيل عملية تبديل السياق ؟ لاسيما إذا أخذنا بعين الاعت بار أن
المعالجات تمتلك عددًا محدودًا من الموارد . فعلى سبيل المثال، يمتلك المعالج مجموعة واحدة
من السجلات، بينما تمتلك كل إجرائية مجموعة خاصة بها من قيم السجلات.
الحل: استخدام مساحة محددة من الذاكرة لحفظ واسترجاع كل المعلومات التي تمثل حالة المعالج
.Process control block لحظة تبديل السياق. وتعرف هذه المساحة بكتلة التحكم بالإجرائية
البنى المستخدمة في إدارة الإجرائيات
كتلة التحكم بالإجرائية
تنشأ كتلة التحكم بالإجرائية لدى إنشاء الإجرائية، وهي أحد أهم بنى المعطيات الموجودة في
8
نظام التشغيل، إذ تستخدم في أغلب ا لوظائف الموجودة ضمن
النظام، كالجدولة، وتخصيص الموارد ومراقبة الأداء.
ماذا يوجد ضمن كتلة التحكم بالإجرائية؟
يتوقف هذا عادة على البنيان الحاسوبي الذي يتعامل معه نظام
التشغيل، ولكن هناك معلومات من المؤكد أنها ستخزن دومًا
ضمن كتلة التحكم بالإجرائية وهي مبينة في الشكل الجانبي.
معلومات التحكم بالإجرائية : مثل حالة تنفيذ الإجرائية،
والشريحة الزمنية المتبقية لها، وأولويتها في حال كان نظام التشغيل يدعم الأولويات.
هوية أو رقم الإجرائية وهوية المستخدم مالك الإجرائية : إذا كان النظام يدعم تعدد
المستخدمين.
Processor Status Word حالة الإجرائية: وهي تتضمن سجلات المعالج وكلمة حالة المعالج
ومعلومات أخرى.
معلومات خاصة بإدارة الذاكرة المخصصة للإجرائية، لاسيما جداول الربط بين الذاكرة
الرئيسية والذاكرة الافتراضية المخزنة على القرص الصلب.
قائمة بالموارد المحجوزة لصالح الإجرائية: كالملفات المفتوحة وبوابات الدخل والخرج.
كتلة التحكم بالإجرائية: ونورد فيما يلي توصيفًا مفص ً لا لبعض هذه الحقول:
معلومات الهوية:
هوية الإجرائية : وهي عادة ماتكون رقمًا صحيحًا فريدًا، ويستخدم هذا الرقم كفهرس
لجدول الإجرائيات.
هوية الإجرائية الأم : وهي معلومة هامة إذ تسمح بتحديد
تبعية الإجرائيات وتمرير نتائج تنفيذ الإجرائية إلى
الإجرائية التي أنشأتها، وهي معلومة هامة جدًا في العديد
.Unix في نظام shell من التطبيقات مثل مفسر الأوامر
معلومات الهوية:
هوية المستخدم صاحب الإجرائية : وهي معلومة هامة
جدًا في الأنظمة م تعددة المستخدمين التي نحتاج فيها إلى حماية المعلومات الخاصة بكل
مستخدم من باقي المستخدمين . إذ تعتمد آلية الحماية على تعريف حقوق استخدام لكل ملف
ولكل مجموعة من المستخدمين وتكون بمثابة قفل، وتكون هوية صاحب الإجرائية بمثابة
المفتاح الذي يقارن مع القفل الموضوع على الملف لدى محاولة فتح الملف.
:CPU state حالة وحدة المعالجة
Process state
Program counter
Registers
Memory limits
List of open files
…...
Process state
Program counter
Registers
Memory limits
List of open files
…...
9
تمثل صورة عن الإجرائية في لحظة ما، وهي تتضمن قيم سجلات المعالج بالإضافة إلى كلمة
المعرفة في EFLAGS ومثال عليها مجموعة السجلات ،Processor Status Word حالة المعالج
والتي تستخدمها كافة أنظمة التشغيل التي تعمل على هذا المعالج. Pentium معالجات
حالة تنفيذ الإجرائية: وهي يمكن أن تأخذ قيمًا عديدة كما سبق وشرحنا.
الموارد التي تحجزها الإجرائية : مثل: ملفات، تجهيزات دخل وخرج، إلخ ...، وهذه المعلومة
هامة جدًا لأن نظام التشغيل قد يضطر إلى تحرير الموارد ف ي حال أنهت الإجرائية عملها دون
تحريرها، مثل إغلاق الملفات المتروكة مفتوحة.
معلومات أخرى:
أولوية الإجرائية: لاسيما إذا كان نظام التشغيل يعمل بالزمن الحقيقي
معلومات المحاسبة: كزمن المعالج المستهلك، الزمن المتاح، إلخ.
حالة الدخل والخرج : بمافيها طلبات الدخل والخرج المعلقة، والتجهيزات المحجوزة،
وقائمة الملفات المفتوحة.
Resource Descriptors موصفات الموارد
غالبًا ما تكون الموارد الحاسوبية قابلة لإعادة الاستخدام، وغير متاحة بكثرة . وتحتاج الإجرائيات
إلى حجزها قبل استخدامها ومن ثم تحريرها لدى نهاية الاستخدام . ومن الممكن أن تكون هذه
الموارد عتادية كالبوابات التسلسلية أو برمجية كبعض البرمجيات المدفوعة والتي لايمكن
استخدامها في آن واحد من قبل عدد من المستخدمين يتجاوزعدد الرخص المباعة . ويحتاج نظام
التشغيل عادة إلى العديد من المعلومات الخاصة بالموارد، مثل:
صف الموارد ونوعها
قائمة بعدد ومعرفات الوحدات المتاحة من المورد المعني
قائمة الإجرائيات المنتظرة للمورد والتي لايمكن تلبية طلباتها
العمليات الأساسية للإجرائيات
:Create إنشاء إجرائية جديدة باستخدام
1) تخصيص معرف جديد وفريد للإجرائية، وغالبًا ما يستخدم عداد لهذا الغرض.
2) حجز الذاكرة اللازمة لكافة أجزاء الإجرائية، بمافيها مساحة الذاكرة اللازمة لتخزين
متحولات البرنامج والمكدس . ويمكن أن تنسخ الإجرائية قيم مساحة الذاكرة من الإجرائية
الأم. بالإضافة إلى حجز الذاكرة اللازمة لكتلة التحكم بالإجرائية.
3) إنشاء كتلة تحكم بالإجرائية جديدة خاصة بالمعرف المذكور أعلاه وإضافتها إلى جدول
10
الإجرائيات في النظام . وتأسيس القيم المختلفة في هذه الكتلة مثل معرف الإجرائية الأم، وقائمة
الإجرائيات الأبناء التي تكون في البداية فارغة، وسجل عداد تنفيذ البرنامج الذي تكون قيمته
البدائية هي عنوان بداية تنفيذ البرنامج، ومؤشر المكدس المستخدم في نظام التشغيل.
:Create إنشاء إجرائية جديدة باستخدام
Ready 4) الحالة الأساسية للإجرائية، والتي غالبًا ماتكون
5) إضافة الإجرائية الجديدة إلى قائمة أبناء الإجرائية الأم
6) تخصيص الموارد اللازمة في البداية
7) تعريف الأولوية البدائية للإجرائية
8) إضافة الإجرائية إلى قائمة الإجرائيات الجاهزة للعمل
Suspend تعليق عمل الإجرائية
1) لايمكن للإجرائية أن تعلق إجرائيات أخرى غير أبنائها
2) في حال كون الإجرائية المعلقة حاصلة على المعالج، توقف عن العمل وتحفظ حالة
المعالج ضمن كتلة التحكم بالإجرائية
3) سحب الإجرائية من قائمة الإجرائيات الجاهزة للعمل ووضعها ضمن قائمة الإجرائيات
المعلقة.
Activate تنشيط الإجرائية
1) تغيير حالة الإجرائية من معلقة إلى جاهزة
2) سحب الإجرائية من قائمة الإجرائيات المعلقة للعمل ووضعها ضمن قائمة الإجرائيات
الجاهزة.
Destroy إنهاء الإجرائية
1) يمكن أن يكون الإنهاء متسلس ً لا، أي ينهى عمل الإجرائية وكافة ابنائها.
2) إذا كانت الإجرائية تعمل (حاصلة على المعالج) يوقف عملها
3) تحرير كافة الموارد المخصصة للإجرائية
4) حذف كتلة التحكم بالإجرائية المخصصة للإجرائية المنهاة.
Change Priority تغيير الأولوية
1) تغير قيمة الأولوية المحفوظة ضمن كتلة التحكم بالإجرائية
2) تغيير موقع الإجرائية في خط الانتطار أو وضعها في خط انتظار جديد لتعكس الأولوية
11
القديمة.
Threads 5. النياسب
سبق ورأينا أن للإجرائية دوران مهمان بالنسبة لنظام التشغيل:
واحدة التنفيذ : أي أن الإجرائية تقوم بتنفيذ سلسلة متتالية من التعليمات التي لايمكن أن
تتداخل مع بعضها البعض.
واحدة تخصيص الموارد : إذ يقوم نظام التشغيل بتخصيص الإجرائية بفضاء العنونة
ومساحة الذاكرة اللازمة لشحن صورة الإجرائية: التعليمات + المعطيات.
هذان الدوران هما في الحقيقة مستقلان كليًا عن بعضهما البعض . ولئن كان مصممو نظم
التشغيل في المراحل الأولى قد دمجوا بينهما دون أن يروا في ذلك مشكلة، فإن التطور الذي
حصل على استخدامات الحاسوب والتغير في طبيعة التطبيقات والتوجه نحو التطبيقات المتعددة
الإجرائيات قد فرض الفصل بينهما في لحظة ما.
ظهر مفهوم النيسب في نهاية الثمانينات، وكان يهدف بشكل أساسي إلى حل مشكلة بطء تبديل
السياق التي تعاني منها الإجرائية نظرًا لضخامة السياق المخصص لها . بالإضافة إلى مشكلة
صعوبة التخاطب بين الإجرائيات بسبب عزل فضاءات العنونة عن بعضها البعض . وكان الحل
هو الفصل بين مفهومي ا لتنفيذ وتخصيص الموارد، بحيث
تبقى الإجرائية هي واحدة تخصيص الموارد، وتعرف
واحدة جديدة للتنفيذ هي النيسب.
يمكن أن تحوي الإجرائية عدة نياسب تشترك كلها في
الموارد المخصصة للإجرائية . لكل نيسب سياق تنفيذ
خاص به مكون من مجموعة سجلات المعالج وعداد
البرنامج ومكدس . أما سياق الإجرائية فهو سياق الموارد،
كصورة الإجرائية في الذاكرة وا لملفات المفتوحة لصالح
. الإجرائية 2
يظهر الشكل التالي الفرق بين النموذج القديم للإجرائية
التي تحوي نيسبًا واحدًا، ونموذج الإجرائية المتعددة
النياسب. ونلاحظ أن الرسم يظهر بوضوح وجود سياق
2 أي أن نظام التشغيل لا يعرف أي نيسب في الإجرائية طلب فتح الملف.
12
خاص بكل نيسب، وسياق آخر مشترك بين كل نياسب الإجرائية.
انقر على الشكل المجاور لترى النسخة المكبرة.
مزايا استخدام النياسب
يصل فرق الزمن بين Solaris اختصار الزمن اللازم لإنشاء وإنهاء واحدة تنفيذ، ففي نظام
إنشاء إجرائية وإنشاء نيسب إلى 30 ضعفًا.
اختصار الزمن اللاز م لتبديل السياق بين وحدات التنفيذ، إذ أن سياق التنفيذ صغير
بالمقارنة مع سياق الموارد . ولانحتاج إلى تبديل سياق الموارد إلا عندما نقوم بتبديل
يصل الفرق إلى 5 Solaris السياق بين نيسبين من إجرائيتين مختلفتين، وفي نظام
أضعاف.
تسهيل عملية التخاطب بين وحدات التنف يذ إلى حد كبير . إذ أصبحت المتحولات الخاصة
بالإجرائية مشتركة بين كل النياسب، بينما كان من الصعب جدًا استخدام متحولات
مشتركة بين الإجرائيات . وكانت عمليات الاتصال بين الإجرائيات بطيئة جدًا لأنها تمر
عبر استدعاء نواة نظام التشغيل.
تتلاءم النياسب العديد من التط بيقات الحديثة، ولاسيما الواجهات التخاطبية للمستخدمين .
فأغلب البرمجيات تحوي على الأقل نيسبين، يقوم الأول بتحديث الواجهة التخاطبية، بينما
يقوم الثاني بتنفيذ العمليات المطلوبة . ومن أبسط الأمثلة : التصحيح التلقائي لملف نصي
أثناء القيام بنسخ ملف. Progress bar بينما يقوم المستخدم بالكتابة، وتحديث دليل التقدم
مستوى تحقيق النياسب
يختلف مستوى الدعم للنياسب بين نظام تشغيل وآخر، فمن الممكن أن تكون النياسب على
وفي هذه الحالة لاترى النواة إلا الإجرائية، ويكون تعريف ،user threads مستوى المستخدم
النياسب وإدارة تقاسم الزمن بينها من مسؤولية مكتبات تعمل على مستوى المستخدم . وتدعم
أغلب أنظمة التشغيل الحديثة، بما فيها لينوكس وويندوز إكس -بي، وماك أوإس، وسولاريس،
أي أن التحكم بالنياسب يتم من قبل النواة. .kernel threads نياسب معرفة على مستوى النواة
سنبين في هذا المقطع العلاقة التي يمكن أن تكون بين نياسب المستخدم ونياسب النواة.
13
عديد لواحد : ويخصص في هذه الحالة نيسب واحد من
النواة مقابل عدة نياسب من مستوى المستخدم . وتتم
إدارة النياسب ضمن مكتبة تعمل على مستوى
المستخدم، وهذا الحل يوفر كثيرًا في موارد الحاسوب
إذ يختصر عدد النياسب اللا زمة. ولكن له سيئة هامة،
وهي أنه يوقف كل النياسب عن العمل إذ قامت إحداهن
بتنفيذ عملية تؤدي إلى التوقف، كما لايمكن لهذا النوع
من الأنظمة أن يستفيد من تعدد المعالجات . ومثال عليها
.GNU Portable Threads هو مكتبة
واحد لواحد : في هذه الحالة ينشأ نيسب من النواة
مقابل كل نيسب من مستوى المستخدم، ومن ميزات
هذا الحل أنه يزيد من درجة التوارد للنظام إذ
لايعاني من عيوب الحالة السابقة . ولكنه بالمقابل قد
يكون مكلفًا، إذ قد يؤدي إنشاء عدد كبير من
النياسب إلى الحد من أداء التطبيقات، لاسيما أن
الزمن اللازم لإنشاء نياسب النواة أكبر بكثير من
نياسب المستخدم . وتلجأ الأنظمة التي تدعم هذا الحل
(لينوكس، وأنظمة ويندوز المختلفة ) إلى فرض حد
لعدد نياسب النواة التي يمكن إنشاؤها.
14
عديد لعديد : وهو حل وسط بين الحلين
السابقين، إذ يسمح بتخصيص عدد من
نياسب النواة أقل أو يساوي عدد نياسب
مستوى ال مستخدم. ويكون عدد نياسب
النواة متناسبًا عادة مع إمكانات الحاسوب
المستخدم، وبذلك نتلافي المشكلات التي
يعاني منها كلا الحلين . وهو مستخدم في
HP- مثل Unix العديد من مشتقات نظام
.UX, Tru64
مكتبات النياسب
تستخدم مكتبات النياسب كواجهة برمجية تسمح لمطوري التطبيق ات باستخدام النياسب في
تطبيقاتهم، وهناك نوعان من المكتبات:
مكتبات تعمل كليًا في مستوى المستخدم بدون أي دعم من النواة: وهي تعتمد على
النموذج عديد لواحد. وتنفذ كافة الأوامر المتعلقة بالنياسب على مستوى المستخدم ولاتعتمد
البتة على استدعاءات النظام.
مكتبات تعمل في مستوى النواة: وفي هذه الحالة تكون هناك استدعاءات للنظام تدعم
النياسب.
ومكتبة ،Win ومكتبة 32 ،POSIX Pthreads هناك حاليًا ثلاث مكتبات هي الأكثر انتشارًا: مكتبة
.Java
نظام التشغيل وخصوصية النياسب
أدى إدخال النياسب كجزء أساسي من نظام التشغيل إلى طرح العديد من التعديلات على
استدعاءات النظام المتعلقة بالتنفيذ، والتي سنوردها هنا تباعًا.
:exec و fork() الاستدعاءات
ينشئ إجرائية جديدة تنفذ عوضًا exec يقوم بنسخ الإجرائية الطالبة، والاستدعاء fork الاستدعاء
عن الإجرائية الطالبة.
15
بنس خ كافة النياسب الموجودة ضمن الإجرائية، أم أنها fork السؤال المطروح هنا : هل تقوم
تكتفي بنسخ النيسب الطالب؟
:exec و fork() الاستدعاءات
الحالة الأولى تقوم .fork لقد اعتمدت بعض أنظمة التشغيل ح ً لا يعتمد على وجود حالتين لاستدعاء
إذ ،exec بنسخ النيسب الطالب فقط، وعلى المبرمج استخدامها عندما يليها مباشر ة استدعاء ل
سيقوم هذا الاستدعاء بإنهاء الإجرائية المنشأة بكافة نياسبها، فلاداعي إذًا لنسخ كافة النياسب .
والحالة الثانية تقوم بنسخ كافة النياسب، وتستخدم عندما لايكون هناك إنهاء مباشر للإجرائية،
وبالتالي يجب أن تكون الإجرائية الجديدة مطابقة تمامًا للإجرائية السابقة.
:Cancellation إلغاء النيسب
الإلغاء هو الإنهاء القسري للنيسب قبل
انتهائه من عمله بشكل طبيعي.
فعلى سبيل المثال، إذا كانت هناك عدة
نياسب تعمل على التوازي لإجراء بحث
ضمن شجرة بيانات، ووصلت إحداها إلى
النتيجة، فلاداعي لمتابعة عمل الأخريات.
هناك حالتان للإلغاء: :Cancellation إلغاء النيسب
فإما أن يكون الإلغاء غير مت زامن بالمرة , ويوقف النيسب فورً ا: وهذا الوضع يطرح
مشكلة الموارد التي قام النيسب بطلبها، إذ أن نظام التشغيل لن يكون قادرًا على استرجاعها
تلقائيها بسبب كونها محجوزة لصالح الإجرائي ة ككل وليس للنيسب
مثل فتح ملف.
أو يكون الإلغاء مؤج ً لا: بحيث يكون بإمكان النيسب أن يتحقق من وجود طلب لإلغائه، وفي
هذه الحالة يقوم بتحرير الموارد التي قام بحجزها قبل إنهاء عمله . ويحتاج هذا النوع من الإلغاء
إلى تعاون المبرمج بالإضافة إلى وجود آليات تسمح بإعلا م النيسب بأن عليه التوقف . ومثال
.Pthreads الموجودة في مكتبة Cancellation points عليها هي نقاط الإلغاء
:Signal handling معالجة الإشارات
لإعلام الإجرائية بحصول حدث ما UNIX الإشارة هي أحد الأدوات المستخدمة في نظام التشغيل
16
مثل القسمة على صفر، أو حدوث خطأ في العنونة. وتتبع الإشارات عادة المنهجية التالية:
1) تولد الإشارة عند حصول حدث ما.
2) يتم تسليم الإشارة إلى الإجرائية.
3) عند وصول الإشارة إلى الإجرائية يجب معالجة هذه الإشارة.
:Signal handling معالجة الإشارات
والمشكلة في الأنظمة المتعدد النياسب هي في تحديد النيسب ال مسؤول عن معالجة الإشارة ضمن
الإجرائية. وتوجد هناك عدة مقترحات بهذا الخصوص:
1) تسليم الإشارة للنيسب المعني بهذه الإشارة.
2) تسليم الإشارة لكل نيسب من نياسب الإجرائية.
3) تسليم الإشارة إلى عدد من نياسب الإجرائية.
4) تحديد نيسب معين لاستلام كل إشارات الإجرائية.
من مبدأ السماح للنيسب بتحديد الإشارات التي يقبلها UNIX وينطلق الحل الأكثر شيوعًا في نظام
والإشارات التي يرفضها، وتسليم الإشارة لأول نيسب يقبلها.
مجموعات النياسب:
يعتبر مخدم الوب أحد أشهر التطبيقات التي تستفيد استفادة كبير من وجود النياسب . وفي الوضع
التقليدي، ينشئ المخدم نيسبًا لمعالجة كل طلب وارد، وهذا أسرع بكثير من إنشاء إجرائية، ولكنه
يمثل رغم ذلك تأخيرًا عن معالجة تنفيذ الطلب، بالإضافة إلى إنهاء عمل النيسب بعد تخديم الطلب
الوارد. وتلجأ العديد من التطبيقات إلى إنشاء عدد كبير من النياسب الجاهزة والقابلة لإعادة
الاستخدام، والتي تنتظر تكليفها بتخديم طلب ثم تعود إلى وضع الانتظار بعد انتهائها من ذلك .
وهذا الحل يمتلك العديد من المزايا، أهمها توفير الزمن اللازم لإنشاء وإنهاء النيسب، بَالإضافة
إلى القدرة على تحديد عد الطلبات التي يمكن تخديمها بآن واحد لئلا يحصل تدهور في أداء المخدم
إذا ما ترك عدد النياسب المستخدمة مفتوحًا.
وجود معطيات خاصة بالنيسب:
فقد عرفنا النياسب كواحدات للتنفيذ تشترك بين بعضها البعض في المعطيات الخاصة بالإجرائية
الأم. ولكن في بعض الحالات هناك حاجة لتخصيص بعض المعطيات لنيسب بعينه، ومثال على
وتكليف كل نيسب بمعالجة مناقلة transactions ذلك استخدا م النياسب في معالجة المناقلات
مستقلة. وتدعم أغلب مكتبات النياسب إمكانية تعريف معطيات خاصة بالنيسب.
17
التخاطب مع المجدول:
هناك العديد من الحالات التي يكون من الضروري فيها تعريف آليات للاتصال بين التطبيقات
والنواة ولا سيما في حالة نموذج عديد لعديد الذي يربط عدة نياسب من مستوى المستخدم مع عدد
من نياسب النواة. والهدف هو الاستفادة إلى الحد الأقصى من إمكانية التوارد المتاحة للتطبيق.
يتعامل نظام التشغيل مع نياسب النواة على أنها معالجات افتراضية يقوم بتخصيصها
للإجرائيات، وال تي تقوم بدورها بتوزيع النياسب من مستوى المستخدم عليها . وقد تحتاج
الإجرائية إلى أكثر من معالج افتراضي لتحسين أدائها، لاسيما إذا كانت نسبة عمليات الدخل
والخرج فيها مرتفعة.
تتخاطب النواة مع التطبيق لإدارة توزيع هذه المعالجات الافتراضية على الشكل التالي:
1) يزود نظام التشغيل التطبيق بعدة معالجات افتراضية، ويقوم التطبيق بجدولة نياسبه عليها
ويسلم هذا ،upcall 2) تعلم النواة التطبيق عن أحداث معينة باستخدام استدعاء صاعد
الاستدعاء إلى إجراء خاص بمكتبة النياسب لإعلامها بالحدث. ويجب أن يعمل الإجراء
الخاص على معالج افتراضي مخصص له.
تتخاطب النواة مع التطبيق لإدارة توزيع هذه المعالجات الافتراضية على الشكل التالي:
3) فإذا كان الحدث متعلقًا بتعليق عمل المعالج الإفتراضي بسبب طلب أحد النياسب لعملية
دخل/خرج مث ً لا، تعلم النواة الإجرائية بأن هناك نيسبًا سيتوقف وتزوده بهوية النيسب،
وتخصص الإجرائية بمعالج افتراضي جديد.
4) يقوم معالج الاستدعاء باستلام المعالج الافتراضي الجديد ويحفظ حالة النياسب التي
ستتوقف عن العمل ويحرر المعالج الافتراضي الذي كانت تستخدمه. كما يقوم بتخصيص
المعالج الجديد لنياسب قادرة على العمل.
تتخاطب النواة مع التطبيق لإدارة توزيع هذه المعالجات الافتراضية على الشكل التالي:
5) عند ورود الحدث الذي تسبب بتعليق عمل المعالج الافتراضي، تبلغ النواة الإدرائية
بورود الحدث، وتحتاج الإجرائية إلى معالج افتراضي لتنفيذ معالج الاستدعاء.
6) تخصص النواة الإجرائية بمعالج افتراضي جديد، أو تطلب سحب أحد المعالجات
الافتراضية التي تستخدمها الإجرائية. يقوم معالج الاستدعاء بإعادة النيسب المعلق إلى قائمة
النياسب الجاهزة للعمل، وبعد انتهائه يخصص المعالج الافتراضي لإحدى النياسب الجاهزة.
18
6. خلاصة
رأينا في هذا الفصل مفاهيم التنفيذ التي يعتمدها نظام التشغيل، وعرف نا الإجرائية كواحدة التنفيذ
وتخصيص الموارد، واستعرضنا حالات التنفيذ المختلفة التي يمكن أن تمر فيها الإجرائية،
بالإضافة إلى البنى المستخدمة لتمثيل الإجرائيات والموارد والعمليات التي يتيحها نظام التشغيل
للتعامل مع الإجرائيات . عرضنا أيضًا الأسباب التي أدت إلى الإبقاء على الإجرائيات كواحدة
لتخصيص الموارد فقط، بينما عرف النيسب كواحدة للتنفيذ . وفي النموذج الجديد، تحتوى
الإجرائية على عدة نياسب تتقاسم الموارد التي تملكها الإجرائية . كما طرحت العديد من النقاط
التي نتجت عن ظهور النياسب والتي لم تكن مطروحة سابقًا.
نهاية الوحدة
المحاضرة الرابعة:
1
التزامن بين الإجرائيات
1. مقدمة
عادة للدلالة على إيجاد علاقة زمنية بين الأحداث. Synchronization يستخدم مصطلح التزامن
مثال: تتم معالجة البيانات بعد الانتهاء من قراءتها.
تعرف هذه الجملة البسيطة حدثين:
قراءة البيانات
معالجة البيانات
وربما كان هذا المثال ب سيطًا وبديهيًا، ولكنه يعبر في آن واحد عن ضوابط للتزامن لايجوز
المساس بها لأنها في صلب تصميم نظام التشغيل . فمن المتعارف عليه في أغلب أنظمة التشغيل
هي عملية متزامنة، أي أن Read أن عملية قراءة البيانات التي تتم باستخدام استدعاء النظام
الاستدعاء لاينتهي ولايعيد نتيجة قبل الانتهاء من قراءة البيانات المطلوبة.
وفي حال وجود عمليات غير متزامنة، فإن العلاقة المذكورة أعلاه لاتعود صحيحة البتة، إذ
سينتهي الاستدعاء دون قراءة كامل البيانات، وسيجد مبرمج التطبيق نفسه مضطرًا لاختبار
صحة البيانات وحجم البيانات كلما طلب استخدامها.
A يمكننا أيضًا تعريف ضوابط للتزامن أكثر تعقيدًا من المثال أعلاه : لايجوز حصول الحدث
في آن واحد، ويعرف هذا النوع من الضوابط باسم "الاستبعاد المتبادل " B والحدث
.Mutual Exclusion
يبدو تحقيق هذه الضوابط سه ً لا جدًا للوهلة الأولى، لا سيما في ضوء التنفيذ ا لتسلسلي للتعليمات
ضمن الإجرائية . ولكن سرعان ما يتبدد هذا الانطباع عندما نأخذ بعين الاعتبار أن نظام التشغيل
يقوم بالتبديل بين الإجرائيات بحيث لايمكن ضمان أي علاقة ترتيب أو تزامن بين تعليمات
إجرائيتين مختلفتين.
يتسم عمل الإجرائيات بأنه غير متزامن أساسًا، ويم كن تشبيهه بشخصين يعملان في مكانين
مختلفين وكل منهما لديه ساعة يستخدمها لترتيب الأعمال التي يقوم بها، ولكن بدون أن يكون
هناك تنسيق بين الساعتين.
ولاتوجد عادة مشكلة في ذلك طالما لايوجد هناك رابط مشترك بين هذه الإجرائيات، ولكن يمكن
أن يكون هناك العديد من الروابط التي تفرض علينا مزامنة هذه الإجرائيات.
بالإضافة إلى علاقة زمنية بين الحدثين :
قراءة البيانات تسبق معالجتها.
2
2. مشكلات التنفيذ المتوارد
( المتحولات المشتركة: مثال( 1
إن أحد أهم وأبسط الأسباب التي تفرض مزامنة الإجرائيات هي قيامها بتعديل متحولات
مشتركة. ودعونا نعرض مثا ً لا على ذلك:
ملاحظة.
ملاحظة هامة : نذكر بأن ترتيب تنفيذ التعليمات ضمن الإجرائية الواحدة هو تسلسلي، وأن هناك
.A1 B2 B علاقة ترتيب كلي بين هذه التعليمات. أي أنه من الخطأ إيراد احتمال التنفيذ 1
3
( المتحولات المشتركة: مثال( 2
المتحولات المشتركة: ذرية التعليمة
يمكن تحقيق ذرية التعليمة بالاعتماد على المعرفة الض منية بآلية عمل نظام التشغيل، إذا حجبنا
كافة المقاطعات أثناء تنفيذ هذه التعليمة . فالتبديل بين إج رائية وأخرى ينتج عن حدوث مقاطعة،
وفي الأغلب مقاطعة زمنية.
وربما كان الحل يبدو فائق البساطة وسهل التحقيق في البداية، ولكن آثاره سيئة جدًا، لابل هي
أسوأ بكثير مما يمكن توقعه، فعملية حجب المقاطعات لايمكن أن تقوم بها البرمجيات 1. يجب إذا
إضافة استدعاء للنظام بهدف حجب وإعادة المقاطعات، وطلب هذا الاستدعاء أينما رأى المبرمج
حاجة لتعديل متحولات مشتركة.
وفي حال كانت هناك سلسلة متتالية من عمليات التعديل، أو كان التعديل ضمن حلقة ستنفذ
10000 مرة:
فهل سنقوم بحجب المقاطعة وإعادتها 10000 مرة ؟
أم أننا سنحجب المقاطعات في بداية الحلقة ونعيدها في النهاية ؟
ومن سيقرر ذلك ؟
1 في حال استخدام البوابة التسلسلية لقراءة محارف، فإن الزمن الحدي لقراءة حرف وارد على خط يعمل
هو من مرتبة 1ميلي ثانية، أي أننا لو لم نستجب للمقاطعة في هذا الزمن، فسيضيع baud بسرعة 9600
الحرف.
4
هل هو المبرمج ؟
؟ وهل سينتج عن ذلك ضياع لبعض المقاطعات التي لن تعالج في الوقت المناسب 2
أسئلة كثير نحن بغنى عنها، وتؤكد أن مبدأ السماح للتطبيقات بحجب المقاطعات سواء مباشرة أو
عن طريق استدعاء النظام هو عملية غير مأمونة العواقب . بالإضافة أن هذا الحل لايعمل في
منظومة متعددة المعالجات.
هناك حل آخر قد لايضمن ذرية التعليمة، ولكنه يحقق الغرض المطلوب . فنحن في الحقيقة يمكن
تعليمات أخرى، ولكن A1 A أي أن تتخلل التعليمتين 2 ، X++ أن نقبل مقاطعة تنفيذ التعليمة
لايجوز أن تكون هذه التعليمات جزءًا من عملية إضافة أخرى على نفس المتحول.
وبالتالي يمكن صياغة ضابط أقل حدة من الذرية لتنفيذ التعليمة:
لايجوز أن تقوم إجرائية أخرى بتعديل المتحول طالما لم تنته الإجرائية من تعديله.
ونصل أخيرًا إلى الخاصة الواجب تحقيقها لضمان صحة تنفيذ الإجرائيات المتواردة:
يجب أن يكون بإمكان المبرمج تعريف مجموعة من التعليمات
التي لايمكن أن تقوم بتنفيذها أكثر من إجرائية واحدة في
لحظة ما.
مثال على ذلك : إذا افتر ضنا مجموعة التعليمات المسؤولة عن إرسال ملف للطباعة، فلايجوز أن
تكون هناك أكثر من إجرائية واحدة تقوم بتنفيذ هذه التعليمات في لحظة ما، وإلا تداخلت
Critical المعلومات في الصفحة المطبوعة. ونسمي هذا النوع من التعليمات بالمقطع الحرج
.Section
إن خاصة المقطع الحرج هي أقل تطلبًا وأثرًا على النظام من خاصة الذرية التي ناقشناها أعلاه،
بالإضافة إلى كونها أكثر شمولية، إذ لاتشمل تعليمة واحدة بل مجموعة تعليمات . ومن الممكن
للمبرمج مث ً لا أن يقوم بتعريف إجراء ما ويطلب أن ينفذ هذا الإجراء بأكمله كمقطع حرج.
ويبقى إذا السؤال الهام والحيوي الذي يحتاج إلى حل: كيف يتم نحقيق المقاطع الحرجة ؟
2 First In First Out
5
المقاطع الحرجة
رأينا في المقطع السابق أن إمكانية تعريف مجموعة تعليمات كمقطع حرج تمثل الحل الأفضل
لمشكلة تداخل تنفيذ الإجرائيات مع بعضها
البعض. ويجب تحقيق الشروط التالية لضمان
حسن عمل المقاطع الحرجة:
لايجوز أن يؤجل دخول إجرائية إلى مقطع
حرج ما لم تكن هناك إجرائية أخرى تعمل
داخلة.
لا توجد أية فرضيات بخصوص سرعة عمل
الإجرائيات أو عددها.
تبقى الإجرائيات داخل المقطع الحرج لزمن
منته.
تحقيق المقاطع الحرجة
سنحاول فيما يلي تجربة الطرق المختلفة لتحقيق المقاطع الحرجة.
المحاولة الأولى:
دعونا نحاول المحاولة الأولى باستخدام الانتظار النشط:
تختبر الإجرائية باستمرار في حال كان بإمكانها دخول المقطع الحرج
لايمكن للإجرائية القيام بأي شيء طالما لم تحصل على السماح لدخول
المقطع الحرج.
هو تابع يعيد نتيجة CheckCriticalSectionPermission وهذا ما توضحه الأسطر التالية، ب اعتبار
إذا كان بإمكان الإجرائية true
الطالبة الدخول إلى المقطع
الحرج.
المحاولة الثانية:
يمكن لكل إجرائية اختبار حالة الإجرائيات الأخرى (قراءة فقط، بدون تعديل).
عند طلب الدخول إلى مقطع حرج، تقوم الإجر ائية بفحص حالة الإجرائيات الأخرى للتأكد
While(!CheckCriticalSectionPermission();
//loop until we get the permission
CS code follows……….
6
من عدم كونها داخل المقطع الحرج.
في حال عدم وجود إجرائيات أخرى، تقوم الإجرائية بتعديل حالتها لإعلام باقي
الإجرائيات بأنها داخل المقطع.
تكمن المشكلة هنا في احتمال حصول تبديل للإجرائيات في المعالج بين المرحلتين 2 و 3، كما
يظهر المثال التالي.
لو تم تغيير الإجرائيات مباشرة بعد نجاح اختبار الإجرائية الأولى، وقبل تعديل حالتها،
وسلمت وحدة المعالجة إلى
الإجرائية الثانية التي لن ترى أن
الإجرائية الأولى قد دخلت ,
وبالتالي ستقوم بدورها بدخول
المقطع الحرج . فإذا عاد التنفيذ
إلى الإجرائية الأولى قبل انتهاء
الثانية من تنفيذ المقطع الحرج،
ستكون هناك إجرائيتان داخل
المقطع الحرج لأن الإجرائية
الأولى ستتابع تنفيذها من حيث توقفت. أي أن هذا الحل غير مقبول.
المحاولة الثالثة:
لاحظنا في المرحلة السابقة أن العملية فشلت بسبب الفصل بين الاختبار والتعديل وعدم إمكا نية
جمعهما في تعليمة واحدة، ويحاول الحل التالي معالجة هذه المشكلة:
تقوم الإجرائية بوضع حالتها بأنها داخل المقطع الحرج
توقف الإجرائية تلقائيًا في حال وجود إجرائية أخرى داخل المقطع الحرج، ولايسمح لها
بالمتابعة إلا بعد انتفاء هذا الشرط
ويبدو لنا ثانية أن هذا الحل ممكن ولن يتكرر الخطأ الذي رأيناه في الحالة السايقة، ولكن حالة
Process 1 Process 2
2-While
(!AllOtherProcessOutsideCS())
While
(!AllOtherProcessOutsideCS())
1- Process1 pass 3- Process2 pass
5- Process1.Status = InsideCS; 4- Process2.Status = InsideCS;
CS code follows………. CS code follows……….
7
أخرى لاتقل خطورة يمكن أن تحصل، كما يظهر في المثال التالي.
لو تم تغيير الإجرائيات مباشرة بعد نجاح اختبار الإجرائية الأولى، وقبل تعديل حالتها،
وسلمت وحدة المعالجة إلى
الإجرائية الثانية التي لن ترى أن
الإجرائية الأولى قد دخلت ,
وبالتالي ستقوم بدورها بدخول
المقطع الحرج . فإذا عاد التنفيذ
إلى الإجرائية الأولى قبل انتهاء
الثانية من تنفيذ المقطع الحرج،
ستكون هناك إجرائيتان داخل
المقطع الحرج لأن الإجرائية
الأولى ستتابع تنفيذها من حيث توقفت. أي أن هذا الحل غير مقبول.
المحاولة الرابعة:
في محاولة لتلافي الاستعصاء الذي ظهر في المقترح السابق، يتم التعديل بالشكل التالي:
تقوم الإجرائية بالتعبير عن رغبتها في الدخول إلى المقطع الحرج وتعدل حالتها بناء
على ذلك.
تفحص الإجرائية حالة باقي
الإجرائيات، وتدخل المقطع في حال عدم
وجود طلب من إجرائيات أخرى.
في حال وجود الطلب، تقوم
الإجرائية بإلغاء رغبتها وإعادة الكرة من
جديد، وذلك حتى تدخل المقطع الحرج.
Process 1 Process 2
2-While
(!AllOtherProcessOutsideCS())
While
(!AllOtherProcessOutsideCS())
1- Process1 pass 3- Process2 pass
5- Process1.Status = InsideCS; 4- Process2.Status = InsideCS;
CS code follows………. CS code follows……….
8
وإن كان هذا الحل مقبو ً لا من حيث أنه لايسمح لأكثر من إجرائية بالدخول إلى المقطع الحرج،
ولكنه غير فعال، إذ ستقضي الإجرائيات على الأ غلب الكثير من الوقت في إعادة الإنتظار حتى
.( تتمكن من الدخول (المرحلة 3
المحاولة الرابعة:
هناك مشكلة أخرى في السيناريو السابق : دعونا نتصور أن هناك إجرائيتان تعبر كل منهما عن
رغبتها في الدخول، ولكنها ترى أن الثانية تريد الدخول فتلغي طلبها، وتعيد الكرة . لايوجد ما
يمنع نظريًا من أن يتكرر هذا الوضع إلى مالانهاية، وهذا الوضع يعرف باسم المجاعة
حيث تبقى الإجرائيات تحاول دخول المقطع الحرج دون أن يتحقق لها ذلك . ومع ،starvation
أن احتمال حدوث هذه المجاعة شبه
معدوم، ولكن لايمكننا في أنظمة التشغيل
الاعتماد على الاحتما لات. وبالتالي فإن
هذا الحل غير محبذ البتة.
حل بيترسون:
الاعتماد على تعليمات خاصة:
لاحظنا سابقًا أن السبب الأساسي في الخلل هو
الفصل بين الاختبار والتعديل، ولذلك لجأنا إلى
التعديل قبل الاختبار وما يتبعه من تعقيدات . تدعم
العديد من الحواسيب، لاسيما تلك الت ي تدعم تعدد
bool TestAndSet(bool *addr)
{
bool res = *addr;
*addr = true;
return res;
}
9
تعمل على الشكل التا ثلي: تقرأ .TST AND SET LOCK (TSL) المعالجات، تعليمة تعرف باسم
التعليمة محتوى الذاكرة وتضعه ضمن سجل ثم تخزن قيمة لاتساوي الصفر ضمن عنوان
الذاكرة المعني . ولايمكن للمعالجات الأخرى التعامل مع العنوان المذكور حتى انتهاء تنفيذ
التعليمة. ويمكن تمثيل عمل هذه التعليمة بالإجرائية التالية على أن يكون عملها غير قابل
للمقاطعة.
ويكون دخول الإجرائية إلى المقطع الحرج على الشكل التالي:
ملاحظة:وهذه الطريقة صحيحة وتعمل في بيئة متعددة المعالجات، ولكنها بدورها تعاني من
مشكلة الانتظار النشط.
3. السيمافور
يعتبر السيمافور أحد أهم الأدوات البرمجية المستخدمة في التزامن بين الإجرائيات، وربما كان
أهمها على الإطلاق.
تعريف
ويشبه السيمافور الأعداد الصحيحة مع وجود ثلاث فوارق:
عند إنشاء سيمافور، يمكن تأسيسه بأي قيمة صحيحة نشاء، ولكن بعد ذلك فإن العمليات
الوحيدة المتاحة هي إضافة أو طرح 1 من قيمته، ولايمكن قراءة هذه القيمة.
عند إنقاص القيمة، إذا كانت النتيجة سالبة، فإن الإجرائية الطالبة يتوقف عملها (تأخذ
ولاتعود إلى العمل إلا بعد أن ترفع إجرائية أخرى من قيمة السيمافور . ،(blocked الحالة
.wait تعرف عملية الإنقاص باسم
إذا كانت قيمة السيمافور سالبة وتقوم إجرائية بزيادة القيمة، يتم إيقاظ إحدى الإجرائيات
.signal المتوقفة وتتابع عملها من نقطة التوقف. وتعرف عملية الزيادة باسم
ترتب الإجرائيات المتوقفة ضمن رتل ملحق بالسيمافور، ويدار الرتل بحسب مبدأ الترتيب
.(FIFO) الزمني 3
بعض الملاحظات الخاصة بالسيمافور:
3 First In First Out
while (TestAndSet(&lock) == true); //just wait,lock is set
Execute Critical section;
Lock = false; // unlock the critical section.
10
لايوجد عمومًا طريقة لمعرفة إذا كانت الإجرائية ستتوقف أم لا قبل إنقاص السيمافور.
عندما تقوم إجرائية بإيقاظ إجرائية أخرى، لاتوجد طريقة لمعرفة أي منهما ستستحوذ
على المعالج وتتابع عملها.
إذا كانت قيمة السيمافور موجبة، فه ذا يمثل عدد الإجرائيات التي بإمكانها إنقاص
السيمافور بدون أن تتوقف. وإذا كانت القيمة سالبة، فهي تمثل عدد الإجرائيات المنتظرة.
V للإنقاص و P هناك أيضًا تسميات أخرى لعملية الإنقاص والزيادة، والأكثر شيوعًا هي
للزيادة, وهي التسميات الأصلية التي اقترحها صاحب فك رة السيمافور . وكانت حجته في
ذلك أنه من الأفضل أن نستخدم اسمًا بدون معنى من أن نستخدم اسمًا معناه غير مناسب.
استخدامات السيمافور
يستخدم السيمافور على نطاق واسع في برمجة التطبيقات المتواردة، ومن أهم مزاياه وضوح
الحل مما يسهل التحقق من صحته , بالإضافة إلى دعم العديد من أنظمة التشغيل له وبفاعلية
عالية.
:Signaling التشوير
أبسط تطبيقات السيمافور، ويستخدم عادة عندما تريد إجرائية أن تخبر إجرائية أخرى
بأنه قد حدث أمر ما . ويسمح التشوير بالتأكد من عدم تنفيذ مقطع معين من البرنامج قبل
.serialization الانتهاء من تنفيذ مقطع آخر، وتسمى هذه العملية بالسلسلة
مثال على التشوير هو حاجة الإجرائية الثانية إلى بيانات تقوم الإجرائية الأولى بإعدادها
ولايمكنها المتابعة بدونها, ويوضح الشكل التالي التحقيق البرمجي لعملية التشوير.
:Rendezvous التواعد
التواعد هو عملية معممة عن التشو ير، بحيث تنتظر كلتا الإجرائيت ين الأخرى وتتابعان
عملهما سوية.
11
ويظهر الشكل التالي مثا ً لا عن عملية التواعد:
Process A Process B
Statement A1 Statement B1
Statement A2 Statement B2
أي أن .B بعد 1 A و 2 ،A بعد التعليمة 1 B والمطلوب في عملية التواعد أن تنفذ التعليمة 2
الإجرائيتان ستتوقفان عن العمل عند الوصول إلى السطر الثاني، ولن تتابعا العمل حتى تتأكد كل
واحدة منهما من الوصول الأخرى إلى نفس النقطة.
ونحتاج لحل هذه المسألة إلى سيمافورين كما نرى في الشكل التالي:
Process A Process B
Statement A1 Statement B1
SemAhere.Signal(); SemBhere.Signal();
SemBhere.Wait(); SemAhere. Wait ();
Statement A2 Statement B2
إن هذا النوع من التزامن مفيد جدًا، إذ أنه يعني في النهاية أن كل إجرائية تعرف أين وصلت
الأخرى، وهذا تزامن كامل بين الإجرائيتين.
قد يخطر على البال استخدام الحل التالي:
Process A Process B
Statement A1 Statement B1
SemBhere.Wait(); SemAhere. Wait ();
SemAhere.Signal(); SemBhere.Signal();
Statement A2 Statement B2
وهو حل سيئ جدًا، لأنه يؤدي إلى حصول استعصاء في المسألة، إذ ستنتظر كل من الإجرائيتين
أن تضيف الأ خرى السيمافور الخاص بها دون أن تتمكن من ذلك . وتعتبر مشكلة الاستعصاء
A1 B1 A2 B2
12
إحدى أهم العقبات التي تؤدي إلى فشل حلول مسائل التنسيق بين الإجرائيات . وإن كانت المشكلة
واضحة في هذه المسألة بالذات، لكن يمكن أن تكون أقل وضوحًا بكثير من ذلك.
الاستبعاد المتبادل
يعتبر ال سيمافور من افضل الأدوات لتحقيق الاستبعاد المتبادل الضروري لتنفيذ المقاطع الحرجة .
ونستخدم لذلك نوعًا خاصًا من السيمافورات يعرف باسم السيمافورات الثنوية
والسبب في تسميتها كذلك هي أن قيمة تاسيسها .Mutex أو أيضًا باسم ،Binary Semaphores
هي واحد. ويوضح الشكل التالي كيفية استخدام السيمافور لتحقيق الاستبعاد المتبادل:
Process A Process B
Mutex.Wait() Mutex.Wait()
//Critical Section code
X++
//Critical Section code
X++
Mutex.Signal () Mutex.Signal ()
في Wait بسبب خواص السيمافور التي سبق وأوضحناها، لايمكن لإجرائيتين أن ت عبرا تعليمة
آن واحد . وبالتالي فإن التعليمات المحصورة بين تعليمتي الإنقاص والإضافة تنفذ باستبعاد
متبادل.
لايسمح عادة بدخول أكثر من إجرائية إلى مقطع حرج، ولكن هناك حالات معممة يمكن أن نقبل
فيها أكثر من إجرائية ضمن مقطع حرج، مع وجود حد أعلى للإجرائيات . ويمكن أن نتعرض
لهذا الوضع عندما نحاول نمذجة مطعم لايسمح بدخول الزبائن إلا إذا كان لديه مكان لجلوسهم .
وفي حال وصوله إلى السعة الكلية، لايمكن دخول زبون جديد ما لم يخرج أحد الزبائن من
الداخل.
يمكن استخدام السيمافورات لحل هذه الحالة المعممة من المقاطع الحرجة . وذلك بتاسيس قيمة
السيمافور على الحد الأعلى للإجرائيات المسموح دخولها إلى المقطع الحرج.
13
الحواجز
هي مفهوم معمم عن التواعد، بحيث يكون عدد الإجرائيات المتواعدة اكثر Barriers الحواجز
. من اثنتين. ومشكلة الحل المعروض أعلاه أنه غير قابل للتعميم على أكثر من إجرائية 4
ويمكن استخدام نموذج الحاجز لحل كثير من المشكلات، مثال عنها هي مسائل المعالجة
التفرعية التي يتم تقسيم المسألة إلى عدد من الأجزاء وتكلف كل إجرائية بمعالجة جزء، ولاينتقل
إلى الخطوة التالية إلا بعد انتهاء كل الإجرائيات من معالجة الجزء الخاص بها . ويوضح الشكل
التالي آلية عمل الحواجز:
Process A Process B Process C
Rendezvous Rendezvous Rendezvous
Action action Action
ويظهر الحل التالي كيفية تنفيذ الحواجز باستخدام السيمافور: نفترض أن لدينا المتحولات التالية:
عدد الإجرائيات التي يجب أن تعبر
n الحاجز هو
4 من غير المعقول أن نستخدم 100 سيمافور في حال كنا نريد أن تتواعد 100 إجرائية
void waitbarrier()
{
//rendezvous
mutex.wait()
count = count + 1
mutex.signal()
if count == n: barrier.signal()
barrier.wait()
barrier.signal()
//action
}
14
count عدد الإجرائيات التي وصلت إلى الحاجز هو
وأساسه بالطبع واحد mutex هناك سيمافور مخصص للاستبعاد المتبادل
مؤسس على قيمة صفر، وهو يبقى مقف ً لا حتى يكتمل عدد barrier لدينا سيمافور آخر
الإجرائيات، وبعدها يفتح السيمافور مباشرة.
حتى يكتمل العدد، وعندها barrier عمل الحاجز بديهي، إذ تقف كل ا لإجرائيات عند السيمافور
تمر الإجرائيات واحدة تلو الأخرى، فكل واحدة تمر تفتح الطريق لمن بعدها.
حل مسائل شهيرة باستخدام السيمافور
هناك العديد من المسائل التي يمكن استخدامها كحالة نموذجية لدراسة السيمافور، وسنورد في
هذا المقطع عددًا منها.
:Producer-Consumer مسألة المنتج والمستهلك
هذه المسألة هي إحدى أشهر مسائل التزامن بين الإجرائيات . وهي مستخدمة في حل الكثير من
المسائل أكثر تعقيدًا. ومبدأ المسألة هو وجود إجرائيتين:
.buffer تنتج "أغراضًا" وتضعها ضمن خزان :Producer إجرائية منتجة
تسحب الأغراض من الخزان لتقوم باستهلاكها. :Consumer إجرائية مستهلكة
أحد أبسط الأمثلة هو الواجهة التخاطبية لنظام التشغيل، حيث يقوم المستخدم بتوليد العديد من
الأحداث مثل الضغط على زر لوحة المفاتيح أو نقر على الفأرة، ويكون بذلك منتجً ا. وتقوم
إجرائية أخرى بأخذ الأحداث المولدة واحدة تلو الأخرى ومعالجتها لتكون بذلك مستهلكًا.
. ويوجد موقع يوضحطريقة عمل هذه الخوارزمية 5
يمكن تلخيص ضوابط التزامن بين الإجرائيتين كما يلي:
تكون حالة الخزان خلال مرحلة الإضافة والسحب غير مستقرة، لذا يجب أن تتم هذه
العمليات ضمن مقطع حرج.
في حال طلبت إجرائية المستهلك سحب أغراض والخزان فارغ، يتعين عليها الانتظار
حتى يضع المنتج أغراضًا فيه.
يمكن أن يكون للخزان سعة قصوى، وفي هذه الحالة يتوقف المنتج عن العمل عند
الوصول إلى السعة القصوى حتى يسحب المستهلك أغراضًا.
لحل هذه المسألة نحتاج إلى سيمافورين:
5 http://gaia.ecs.csus.edu/~zhangd/oscal/ProducerConsumer/ProducerConsumer.html
15
.Mutex الأول يستخدم لتحقيق الاستبعاد المتبادل ويسمى
.Items الثاني يمثل عدد العناصر في الخزان ويسمى
برنامج المنتج:
يقوم المنتج بإنتاج غرض، ثم
يدخل المقطع الحرج ويضيف
عنصرًا إلى الخزان، ثم ينفذ
تعليمة الإضافة على السيمافور
ليزيد من عدد العناص ر items
في الخزان ويخرج من المقطع
الحرج، هذا الحل لايدعم السعة القصوى للخزان.
برنامج المستهلك:
قبل أن يقوم المستهلك باستهلاك غرض، يطلب
ليتأكد من وجود غرض items إنقاص السيمافور
في الخزان، وبعدها يدخل المقطع الحرج ليسحب
الغرض ومن ثم يخرج من المقطع الحرج.
يمثل ,capacity في حا ل أردنا إضافة مفهوم السعة القصوى، علينا استخدام سيمافور ثالث
الاماكن المتبقية ضمن الخزان، ويقوم المنتج بإنقاصه قبل الدخول إلى المقطع الحرج، كما يقوم
المستهلك بإضافته بعد انتهائه من الاستهلاك . وتصبح البرامج على الشكل التالي (الإضافة باللون
الأحمر):
void producer ( void )
{
while (true)
{
produce ( object );
wait ( mutex ); //mutex is semaphore
put (object);
signal ( mutex );
signal ( items );
}
}
void consumer (void)
{
while(true)
{
wait (items);
wait (mutex);
remove (object);
signal (mutex);
consume (object);
}
}
void producer ( void )
{
while (true)
{
wait (capacity);
produce ( object );
wait ( mutex );
// mutex is semaphore
put (object);
signal ( mutex );
signal ( items );
}
}
void consumer ( void )
{
while(true)
{
wait ( items );
wait ( mutex );
remove ( object );
signal ( mutex );
signal (capacity);
consume ( object );
}
}
16
قبل الدخول في المقطع الحرج وليس capacity ملاحظة هامة : لماذا نقوم بإنقاص السيمافور
بداخله ؟ هل هناك فرق في النتيجة ؟ والجواب.
بكل بساطة هو نعم . في حال إنقاص السيمافور داخل المقطع الحرج ، فإننا نتعرض إلى
استعصاء في النظام إذ قد تتوقف إجرائية المنتج عن د هذا السيمافور بسبب الوصول إلى السعة
القصوى. وفي هذه الحالة لن تتمكن من تحرير المقطع الحرج، وستبقى كافة الإجرائيات
الأخرى منتظرة عند مدخل المقطع الحرج ولن تتمكن من الدخول وبالتالي تتوقف كافة مكونات
المسألة عن العمل.
:Readers-Writers مسألة الكتاب والقراء
تسمح هذه المسألة بنمذجة الكثير من بنى المعطيات المعرضة للقراءة والتعديل من قبل عدد كبير
من الإجراءات المتواردة، كقواعد البيانات مث ً لا. وتلخص ضوابط التزامن لهذه المسألة على
الشكل التالي:
يمكن لأي عدد من الإجرائيات التي ترغب في القراءة بالتواجد داخل المقطع الحرج.
تحتاج الإجرائية التي تقوم بالتعديل إلى الولوج الحصري إلى البنى المراد تعديلها،
وبالتالي يجب أن تكون وحيدة داخل المقطع الحرج.
أي يمكننا القول أنه لايمكن للإجرائية طالبة التعديل دخول المقطع الحرج في حال وجود أية
إجرائية أخرى تقوم بالقراءة أو الكتابة . وعندما تكون هذه الإجرائية في داخل المقطع الحرج،
فإنها تمنع أية إجرائية أخرى من الدخول، سواء بهدف القراءة أو الكتابة.
. ويوجد موقع يوضح طريقة عمل هذه الخوارزمية 6
يمثل عدد الإجرائيات التي تقوم readers نستخدم من أجل الحل المتحولات التالية : عداد
تكون CSEmpty وسيمافور ثاني ،mutex بالقراءة، وسيم افور مسؤول عن حماية العداد المذكور
قيمته واحد إذا لم تكن هناك أية إجرائية داخل المقطع
الحرج، وصفرًا في حال وجود أية إجرائية أخرى داخل
المقطع الحرج.
حل إجرائية الكاتب بسيط جدًا، ينتظر الكاتب عدم وجود أية إجرائية داخل المقطع الحرج، وذلك
.CSEmpty باستخدام السيمافور
أما بشأن القارئ فالموضوع معقد بعض الشيء، إذ يجب عدم الدخول في حال وجود كاتب، كما
يجب عدم منع القارئين الآخرين من الدخول في حال تمكنت الإجرائية من ذلك . ويمكن تلخيص
6 http://gaia.ecs.csus.edu/~zhangd/oscal/ReaderWriter/ReaderWriter.html
int readers = 0;
mutex = Semaphore(1);
roomEmpty = Semaphore(1);
17
فكرة الحل في أن أول قارئ يدخل
يوصد الباب في وجه الكت اب،
وآخر قارئ يخرج يفتح الباب
للكتاب المنتظرين.
لايحوي الحل احتمال وجود
استعصاء، ولكن تظهر لدينا هنا
مشكلة جديدة قد لاتقل خطورة عن
الاستعصاء، وتعرف باسم المجاعة
إذ من الممكن أن يصل كاتب وينتظر بسبب وجود قراء في الداخل . ويبقى الكاتب ،starvation
ينتظر الدخ ول إلا مالانهاية بينما يتوافد القراء ويخرجون ويبقى هناك على الأقل قارئ واحد
يمنع الكاتب من الدخول.
يمكن تعديل الحل لتفادي هذه المشكلة بالشكل التالي:
كافة القراء الذين يصلون بعد وصول الكاتب المنتظر لايدخلون المقطع الحرج، بل ينتظرون
انتهاء الكاتب ليدخلوا، و بذلك يكون انتظار الكاتب منتهيًا، إذ عليه فقط انتظار خروج القراء
الذين كانو موجودين لحظة وصوله.
:Dining philosophers مسألة عشاء الفلاسفة
ربما كانت هذه المسألة أكثر مسائل السيمافور شعبية، إذ لا يمكن أن يصدر كتاب عن أنظمة
التشغيل دون التطرق إليها، وكلما ظهرت آلية جديدة من آليات التزامن، يهرع أصحابها إلى
إظهار سهولة حل مسألة الفلاسفة باستخدام هذه الآلية.
يجلس خمسة فلاسفة في حلقة حول طاولة، وأمام كل منهم طبق من المعكرونة لاينتهي محتواه،
وهناك شوكة بين كل صحنين، أي أن أمام كل فيلسوف شوكتان : واحدة على يمينه وأخرى على
يساره.
يقضي الفيلسوف حياته في التفكير وتناول الطعام من طبق
المعكرونة، وليتمكن من تناول الطعام يحتاج إلى تناول
الشوكتين ليتمكن من الأكل . وبعد الإنتهاء من الأكل،
ينظف الفيلسوف الشوكتين ويعيدهما إلى مكانهما جاهزتين
للاستخدام من جديد .
mutex.wait()
readers += 1
if readers == 1:
roomEmpty.wait() # first in locks
mutex.signal()
# critical section for readers
mutex.wait()
readers -= 1
if readers == 0:
roomEmpty.signal() # last out unlocks
mutex.signal()
P0
P3
P2
P1
P4
18
. ويوجد موقع يوضح طريقة عمل هذه الخوارزمية 7
يعتمد الحل البديهي على تمثيل كل شوكة بسيمافور قيمته الأساسية واحد، بحيث تمثل عملية
الإنقاص حجز الشوكة، وعملية الزيادة تحرير
قبل تناول الطعام i الشوكة. ويقوم الفيلسوف رقم
الذي يقوم بطلب GetForks(i) باستدعاء الإجراء
عن طريق إنقاص كل من ، i+ و 1 i الشوكتين رقم
السيمافورين الموافقين . وبعد الإنتهاء من تناول
الطعام، يقوم الفيلسوف باستدعاء الإجراء
الذي يقوم بزيادة ، ReleaseForks(i)
السيمافورين الذين سبق إنقاصهما.
للأسف فإن الحل البديهي غير مقبول، إذ يمكن أن يحصل
استعصاء في الحالة التالية: دعونا نتصور أن كل إجرائية
بين إجرائيات الفلاسفة حجزت الشوكة على يمينها، وتم
تبديل المعالج قبل أن تحجز الشوكة على يسارها. سنجد
نفسنا في وضع يحمل فيه كل فيلسوف شوكة في يده اليمنى
دون أن يتمكن من الحصول على الشوكة الأخرى لأنها
محجوزة، وهذا يمثل استعصاء.
نقترح لحل الاستعصاء أن يقوم الفيلسوف باختبار حالة الشوكة التي على يساره قبل التورط
بمحاولة إنقاص السيمافور، فإذا كانت الشوكة محجوزة يقوم بإعادة الشوكة على يمينه إلى
الطاولة، ويعيد طلب الشوكتين من جديد . هذا الحل يعقد الأمور بعض الشيء، إذ أنه يخالف أحد
المبادئ الأساسية في السيمافور : لايمكننا معرفة قيمة السيمافور، كل ما يمكننا هو طلب
الإنقاص، فإذا كانت قيمة السيمافور صفرًا أو أقل يتوقف تنفيذ الإجرائية . بالإضافة إلى كونه
يعاني من مشكلة المجاعة، إذ من الممكن أن يتكرر الوضع إلى مالانهاية.
ملاحظة ه امة جدً ا: إن احتمال ظهور المجاعة أو الاستعصاء هو شرط كاف لرفض الحل أو
اعتباره غير مرغوب فيه، وذلك مهما كان الاحتمال ضئي ً لا.
هناك العديد من الحلول التي لاتعاني من مشكلة الاستعصاء، وسنقتصر هنا على الحلول
الأساسية فقط.
7 http://www.doc.ic.ac.uk/~jnm/concurrency/classes/Diners/Diners.html
Semaphore fork[5] = 1;
void GetForks(int i) {
fork[i].down();
fork[i+1].down();
}
void ReleaseForks(int i) {
fork[i].up();
fork[i+1].up();
}
19
يظهر الشكل التالي ح ً لا يعتمد على كسر حلقة الانتظار التي تسبب الاستعصاء.
فالسبب في ظهور الاستعصاء يعود إلى تشكل
حلقة في بيان الانتظار الذي يمكن بناؤه باستخدام
القاعدة البسيطة : إذا افترضنا أن الإجرائيات
تشكل نقاطًا ضمن بيان، يرسم قوس من النقطة
لأن B تنتظر A في حا ل كون B باتجاه النقطة A
الحصول عليه . والحل المطروح هنا يتلخص في وجود فيلسوف واحد A حجزت موردًا تريد B
"أعسر"، يطلب الشوكة اليسرى قبل اليمنى . وفي هذه الحالة، لن تتكون الحلقة ولن يحصل
استعصاء.
هذا الحل ممتاز لهذه المسألة، ولكنه غير قابل للتعميم بسهولة في مسائل أ خرى غير مسألة
الفلاسفة، إذ يحتاج إلى وضع تصور دقيق لبيان الانتظار واحتمالات تشكل الحلقات ضمنه.
حل آخر يستند على مبدأ الحد من عدد الإجرائيات التي تتنافس على الموارد بحيث يكون لدينا
دومًا ما يكفي من الموارد للمحافظة على عمل النظام . في حالة عشاء الفلاسفة، يم كننا بسهولة
إثبات أنه لو سمحنا فقط لأربعة فلاسفة بتناول
الطعام عوضًا عن الخمسة، فلن يكون هناك
استعصاء. إذ في أسوأ الحالات، سيكون لدينا
أربعة فلاسفة يحمل كل منهم شوكة، وستبقى
شوكة غير محجوزة، مع وجود فيلسوف على
P1
P5
P4
P3
P2
w
ait
in
w
ait
in
waitin waitin
waitin
void LeftHandedGetForks(int i)
{
fork[i+1].down();
fork[i].down();
}
void GetForks(int i)
{
footman.wait()
fork[right(i)].wait()
fork[left(i)].wait()
}
void ReleaseFors(int i)
{
fork[right(i)].signal()
fork[left(i)].signal()
footman.signal()
}
20
اليمين وآخر على اليسار يحمل كل منهما شوكة ومس تعد لأخذ الشوكة المتاحة . يمكننا أيضًا
إثبات أن هذا الحل لايحوي على مجاعة.
ولتقييد عدد الإجرائيات التي يمكن أن تأكل في نفس الوقت، نقوم بإضافة سيمافور جديد مؤسس
على القيمة (عدد الفلاسفة- 1). وهذا الحل مبين في الشكل التالي:
الذي قدمه في Andrew Tanenbaum الحل الأخير يعرف باسم حل تانينبوم، نسبة إلى صاحبه
كتابه الذي يعد من أشهر كتب أنظمة التشغيل . يعتمد الحل على فكرة شبيهة بالمبدأ الأساسي
الذي من أجله أوجد السيمافور:
عدم الفصل بين الاختبار والتعديل. إن المشكلة التي يعاني منها الحل الأول سببها الفصل بين
عمليتي الحجز.
ومنه مقترح الحل:
حجز الشوكتين في آن واحد، فإما يحصل الفيلسوف على الشوكتين، أو يبقى منتظرًا دون أن
يحجز إحداهما . وبتعبير آخر، يمكن للفيلسوف تناول الطعام في حال كون جاريه الاثنين
لايأكلان.
الحل
لايوجد استعصاء في هذا الحل لأن السيمافور الوحيد الذي يمكن اس تخدامه من قبل أكثر من
ولاتقوم أية إجرائية بإجراء عملية قد ينتج عنها ،mutex إجرائية هو سيمافور الاستبعاد المتبادل
انتظار داخل المقطع الحرج . وبالمقابل، أثبت أن هذا الحل يعاني من مشكلة المجاعة، ولكننا لن
ندخل في تفاصيل ذلك بسبب التعقيد المرتبط بذلك.
في هذا الحل لم نعد بحاجة لتمثيل كل شوكة بسيمافور، وإنما نعتمد على التمثيل التالي:
مصفوفة من خمسة متحولات يمثل كل منها حالة فيلسوف، ويمكن للفيلسوف أن يأخذ
حالة التفكير أو الجوع أو تناول الطعام (السطر الاول من الكود في الشكل التالي).
مصفوفة من خمسة سيمافورات مؤسسة على الصفر، يستخدم كل منها لجعل الفيلسوف
الموافق ينتظر (السطر الثاني من الكود في الشكل التالي).
سيمافور واحد يستخدم لحماية المتحولات المذكورة أعلاه من التغيير بدون تنسيق
(السطر الثالث من الكود في الشكل التالي).
ويكون الحل على الشكل التالي:
21
i وهو يقوم بفحص ما إذا كان بإمكان الفيلسوف رقم ،test(i) العملية الأساسية هي في التابع
أن يتناول الطعام، وفي حال الإيجاب، تتم إضافة السيمافور الخاص بانتظار الفيلسوف المعني.
هناك طريقتان يمكن لفيلسوف أن يتناول الطعام فيها:
يمكن أن يطلب الحصول
على الشوكتين ويجد أنهما
غير محجوزتين أي لا أحد
من الجارين يأكل،
فيحجزهما ويبدأ الطعام.
أو يمكن أن تكون إحدى الشوكتين محجوزة أي أحد الجارين يأكل ، وفي هذه الحالة
لايمكن للفيلسوف المتابعة ويتوقف بانتظار أن يتغير الوضع . فعندما ينتهي كل فيلسوف
من تناول الطعا م، يقوم باختبار إذا كان جاراه راغبين في تناول الطعام ويضع الشوكتين
تحت تصرفهما.
state = ['thinking']*5
sem = [Semaphore(0) for i in range(5)]
mutex = Semaphore(1)
The initial value of state is a list of 5 copies of 'thinking'.
sem is a list of 5 semaphores with the initial value 0.
void test(int ai)
{
if (state[i] == hungry and_
state (left (i)) != eating and_
state (right (i)) != eating)
state[i] = eating
sem[i].signal()
}
22
ملاحظة.
Monitor 4. المراقب 8
رغم سهولة استخدام السيمافور وتوافره في كافة أنظمة التشغيل، وكونها كافية لحل جميع
C مشكلات التزامن التي يمكن أن توا جهنا، فإنها تبقى "منخفضة المستوى ". ويمكن مقارنتها بلغة
في البرمجة، وهي لغة تسمح ببرمجة كافة التطبيقات التي نريدها، إلا أنها لاتحوي على العديد
من المفاهيم التي تريح المبرمج . وبنفس الطريقة، فإن الحلول باستخدام السيمافور غالبًا ما تكون
طويلة وتحتاج إلى دقة كبيرة، ويمكن أن تؤدي أخطاء بسيطة فيها إلى ظهور استعصاءات أو
مجاعة.
ورغم استخدام السيمافور لتحقيق المقاطع الحرجة، فإن العملية تبقى يدوية ومعتمدة على وضع
تعليمات السيمافور في الموقع المناسب، ويبقى التأكد من صحة البرنامج متروكًا كليًا على عاتق
المبرمج.
8 قد يكون المصطلح غير مقنعًا، ولكن لايوجد بديل له في الوقت الراهن
state = ['thinking'] * 5
sem = [Semaphore(0) for i in range(5)]
mutex = Semaphore(1)
The initial value of state is a list of 5 copies of 'thinking'.
sem is a list of 5 semaphores with the initial value 0.
void GetForks(int i)
{
mutex.wait();
state[i] = hungry;
test(i);
mutex.signal();
sem[i].wait();
}
void ReleaseForks(int i)
{
mutex.wait();
state[i] = thinking;
test(right(i));
test(left(i));
mutex.signal();
}
void test(int ai)
{
if (state[i] == hungry and
state (left (i)) != eating and
state (right (i)) != eating)
state[i] = eating
sem[i].signal()
}
}
23
المراقب هو أداة أعلى مستوى من السيمافور، تسمح بتعريف المقطع الحرج بشكل تلقائي وبدون
حصول أخطاء في تحقيقها . ويتكون المراقب من بيانات على شكل مجموعة متحولات، بالإضافة
إلى إجراءات تتعامل مع هذه المتحولات . يحوي المراقب أيضًا على متحولات من نوع خاص
.conditions يسمى الشروط
يحقق المراقب ومتحولاته الخصائص التالية:
لايمكن التعامل مع بيانات المراقب إلا باستخدام الإجراءات الخاصة بالمراقب
تعمل الإجراءات باستبعاد متبادل بين بعضها البعض، أي لايمكن في لحظة ما أن يكون
هناك أكثر من إجراء واحد داخل المراقب.
.signal و wait يمكن التعامل مع متحولات الشروط عبر تعليمتين فقط، وهما
على نفس signal إلى توقف الإجرائية الطالبة بانتظار وصول تعليمة wait تؤدي عملية
المتحول.
إلى متابعة إجرائية واحدة متوقفة عند الشرط الموافق، وفي حال signal تؤدي عملية
عدم وجود إجرائية متوقفة، لايكون لها أي مفعول.
إلى تحرير المراقب بحيث يكون بإمكان إجرائية ثانية تنفيذ wait يؤدي طلب تعليمة
تلقائيًا P يتوقف عمل Q إجرائية أخرى P إجراءات المراقب. فإذا أيقظت إجرائية
من Q بانتظار خروج
المراقب أو توقفها عند
شرط آخر.
ويوجد موقع يوضح طريقة
. عمل هذه الخوارزمية 9
ويظهر الشك ل التالي ح ً لا
لمسألة المنتج والمستهلك
باستخدام خزان منتهى السعة
مكتوبًا باستخدام مراقب.
ونلاحظ أن كتابة الحل أسهل
بكثير من استخدام السيمافور،
9 http://gaia.ecs.csus.edu/~zhangd/oscal/monitor/monitor.html
monitor BoundedBuffer
{
private Buffer b = new Buffer(10);
private int count = 0;
private Condition nonfull, nonempty;
public void add(Object item)
{
if (count == 10) nonfull.wait();
b.add(item);
count++;
nonempty.signal();
}
public Object remove()
{
if (count == 0) nonempty.wait();
item result = b.remove();
count--;
nonfull.signal();
return result;
}
}
24
إذ ليس على المبرمج أن يحاول حماية متحول بعينه أو مجموعة تعليمات محددة . وذلك لأن
الإجراء بأكمله ينفذ باستبعاد متبادل.
هذه الخاصة الأخيرة ضرورية لضمان صحة عمل الإجرائيات، إذ أنها تعطي المنتظر أولوية
على المحرر، وذلك بهدف السماح للمنتظر بمتابعة العمل مباشرة دون معاودة التحقق من صحة
هي التي ستتابع العمل، فربما قامت بتنفيذ P الشرط الذي توقف من أجله. فلو كانت أجرائية
بالمتابعة . وهذا يؤدي للأسف إلى مشكلة في أداء Q تعليمات تغير من الشرط الذي سمح ل
المراقب بسبب كثرة عمليات التبديل بين الإجرائيات.
دعونا نأخذ مثال الخزان أعلاه ونلاحظ ماسيحصل عندما تتوقف إجرائية عند الشرط
.Add وتقوم إجرائية أخرى بتنفيذ إجراء ،nonempty
nonempty.signal() يضيف المنتج الغرض إلى الخزان ويستدعي .i
يتوقف المنتج مباشرة عن العمل ويتابع المستهلك العمل .ii
يسحب المستهلك الغرض من الخزان ويترك المراقب .iii
هي آخر تعليمة في الإجراء، signal يتابع المنتج عمله، وباعتبار أن تعليمة .iv
يخرج المنتج من المراقب.
هناك عملية تبديل في السياق بين المنتج والمستهلك وبالعكس، وهي تؤدي إلى الحد من أداء
كبديل notify النظام ككل في حال الاعتماد الكثيف على المراقبين . ولتلافي ذلك، أضيفت عملية
تتابع عملها دون توقف، notify والفرق بينهما هو أن الإجرائية التي تطلب .signal عن تعليمة
إلى إعادة اختبار الشرط الذي توقفت notify بينما تحتاج الإجرائ ية المتوقفة والتي حررتها عملية
من أجله من جديد. وبالتالي فإن الاختبار السابق الذي كان:
والذي كان اختبارًا لمرة واحدة،
يجب أن يتحول إلى حلقة ليصبح:
if (count==10)
{
nonfull.wait();
}
while (count==10)
{
nonfull.wait();
}
25
لايوجد في لغات البرمجة
تحقيق شائع للمراقبين، ولكن
هناك مايشبه ا لمراقب في لغة
جافا، وهو الطرائق المتزامنة
.synchronized methods
والفرق هو أننا لانحتاج في
لغة جافا إلى توصيف صف
معين من الأغراض على أنه
مراقب، فكل غرض مرشح
ليكون مراقبًا. ويحقق
التزامن عن طريق الطرائق
المتزامنة التي تنفذ تلقائيًا
باستبعاد متبادل، كما أن
جافا لاتحوي متحولات
شروط مثل تلك الموجودة
و c.wait() في المراقب، بل هناك متحول واحد مضمر غير معرف . فعوضًا عن كتابة
ويظهر الشكل الجانبي ح ً لا لمسألة المنتج والمستهلك .notify() و wait() نكتب ببساطة ،c.notify()
باستخدام خزان منتهى السعة مكتوبًا بلغة جافا.
ملاحظة.
والذي يقوم بإيقاظ كافة الإجرائيات المتوقفة بسبب notifyall() ونلاحظ أننا نستخدم هنا إجراء
التي بحسب توصيف جافا توقظ إجرائية واحدة غير محددة . notify عوضًا عن ،wait تنفيذ
فلايمكننا أن نضمن مث ً لا أن الإجرائية التي ستستيقظ بعد إضافة عنصر هي إجرائية متوقفة في
انتظار وجود عناصر ضمن الخزان.
5. الرسائل
استندت كافة آليات التزامن السابقة على وجود متحولات مشتركة بين الإجرائيات، ولكن ماذا
يحصل لولم تكن هناك ذاكرة مشتركة ؟
الحاجة إلى الرسائل:
class BoundedBuffer
{
private List b = new ArrayList(10);
private int count = 0;
synchronized public void add(Object item)
{
while (count == 10)
{
wait();
}
b.add(item);
count++;
notifyAll();
}
synchronized public Object remove()
{
while (count == 0)
{
wait();
}
Object result = b.remove(0);
count--;
notifyAll();
return result;
}
}
26
لم تعد المشكلة هي في إلغاء التضارب بين الإجرائيات، ولكن في تأمين آلية اتصا ل وتعاون
بينها. نستخدم لهذا الغرض آلية أخرى هي الرسائل، وهي موجودة في جميع أنظمة التشغيل،
والشكل العام لآلية الرسائل هو وجود إجرائين خاصين لهذا الغرض:
send(destination, message) إرسال
receive(source, message_buffer) استقبال
ويختلف تحقيق هذه الإجراءات من نظام لآخر.
. ويوجد موقع يوضح طريقة عمل هذه الخوارزمية 10
متغيرات تحقيق الرسائل: التسمية:
يمكن تحديد المصدر والوجهة مباشرة باستخدام هوية الإجرائية، أو بشكل غير مباشر باستخدام
وهناك العديد من الأسماء المستخدمة .message queue أو رتل رسائل mailbox علبة بريد
لتسمية علبة البريد في الأنظمة المختلفة، ولكنها جميعها تعمل بحسب المبدأ نفسه : خزان رسائل
يسمح بإضافة وسحب الرسائل بحسب آلية المنتج والمستهلك، وعلى الأغلب يكون سحب
الرسائل بنفس ترتيب وصولها . يمكن أيضًا أن تكون علبة البريد مخصصة لإجرائية واحدة
وتسمى في هذه الحالة بوابة.
كما أن الاستلام ،Multicast تسمح بعض الأنظمة بإرسال رسالة إلى عدة إجرائيات في آن واحد
غالبًا ما يكون مفتوحًا، أي يمكن للمستلم أن يستلم رسالة من أية إجرائية، وليس من إجرائية
بعينها.
anycast multicast
broadcast unicast
متغيرات تحقيق الرسائل: التزامن:
القاعدة الأكثر شيوعًا هي أن تكون عملية الإرسال غير موقفة، أي أن المرسل يرسل رسالته
ويتابع عمله بغض النظر عن كون المستقبل قد حصل عليها أم لا . أما عملية الاستقبال فهي
موقفة لأن الإجرائية لا تتابع عملها قبل انتهاء الاستقبال وحصولها على البيانات . وفي هذه
10 http://gaia.ecs.csus.edu/~zhangd/oscal/message/message.html
27
الحالة لايكون هناك تزامن حقيقي بين المرسل والمستقبل لأن المرسل لايعرف إذا كان المستقبل
قد حصل على رسالته أم لا.
وفي هذه .Rendezvous النوع الآخر هو الرسائل المتزامنة التي تعمل بحسب مبدأ الموعد
الحالة يتوقف المرسل والمستقبل ولايتابعان عملهما إلا بعد وصول الرسالة إلى المستقبل.
متغيرات تحقيق الرسائل: التخزين:
نظرًا لوجود فصل بين فضاء العنونة الخاص بالإجرائيات، يقوم نظام التشغيل بنسخ الرسالة في
ذاكرة داخلية خاصة به قبل نسخها ثانية في مساحة الذاكرة الخاصة بالمستقب ل. ومن الممكن ألا
يسمح نظام التشغيل بتخزين الرسائل بالمرة، ويقوم بتسليمها مباشرة للمستقبل . وفي هذه الحالة،
تكون كافة الرسائل المرسلة متزامنة لأن المرسل سيضطر إلى التوقف في انتظار المستقبل.
استخدامات الرسائل
تستخدم الرسائل في بناء العديد من التطبيقات الها مة، ولاسيما تطبيقات المخدم /الزبون
والتطبيقات الموزعة التي لاتتوافر فيها في أغلب الأحيان ذاكرة مشتركة بسبب كونها تعمل على
حواسيب مختلفة.
تستخدم الرسائل أيضًا كأداة للاتصال والتزامن بين الإجرائيات في أنظمة التشغيل المركزية غير
الموزعة، وذلك كبديل عن آليات ال ذاكرة المشتركة ومشكلاتها التي سبق واستعرضناها في هذا
الفصل، أو كآلية للاتصال المحمي بين الإجرائيات التي لاتثق ببعضها البعض.
بحيث UNIX صمم نظام التشغيل
يستخدم الرسائل كآلية أساسية
للاتصال بين الإجرائيات . إذ لاتوجد
ذاكرة مشتركة بين الإجرائيات ولكنها
تتصل بي ن بعضها البعض باستخدام
وهي عبارة عن قناة ،pipes المواسير
للاتصال بين مرسل ومستقبل توصل
الرسائل بحسب ترتيب إرسالها .
ويمكن للمرسل أن يكتب فيها كما
التسمية هنا غير مباشرة، .read ويقرأ منها المستقبل وكأنه يقرأ من ملف ،write يكتب في ملف
إذ يمكن تشبيه المواسير بأرتال الرسائل. أما فيما يخص التزامن فهو يطبق القاعدة الشائعة:
Client
Client
Client
Client
Client
Masseges
Masseges
Masseges
Masseges
Masseges
28
الإرسال غير موقف والاستقبال موقف.
يقوم نظام التشغيل بتخزين المعلومات المرسلة إلى حين استلامها، ولكن عملية التخزين تلغي
الحدود بين الرسائل . أي أن المستخدم والمرسل يتعاملان مع الرسائل على أنها سلسلة من
المحارف، وعملية الإرسال هي إضافة مزيد من المحارف إلى الخزان الذي يقرأ منه المستقبل.
مثال.
6. خلاصة
التزامن بين الإجرائيات هو علاقة تفرضها متطلبا ت المنظومة التي تمثلها الإجرائيات، والتي قد
تحتاج إلى التعاون والتنسيق بين بعضها البعض . ولتحقيق التزامن بين الإجرائيات نحتاج إلى
حل عديد من المشكلات، أهمها مشكلة المقطع الحرج والخصائص المطلوبة منه . وتقدم أنظمة
التشغيل عددًا من الآليات التي تسمح بتمثيل علاق ة التزامن وحل مشكلة المقطع الحرج، وتنقسم
هذه الآليات بشكل عام إلى جزئين : الجزء الأول ويعتمد على الذاكرة المشتركة، ويحوي آليات
السيمافور والمراقب، وهو أكثر شيوعًا في النظم المركزية . ويعتمد الجزء الثاني على تبادل
الرسائل وهو أكثر شيوعًا في الأنظمة الشبكية وا لموزعة حيث لاتوجد ذاكرة مشتركة . وتدعم
أغلب نظم التشغيل كلتا الآليتين تاركة الاختيار لمصمم التطبيقات ليختار الآلية الأنسب.
multicast
anycast
unicast
broadcast
29
نهاية الوحدة
المحاضرة الخامسة:
1
جدولة الإجرائيات
1. مقدمة
تعريف الجدولة
سبق وتكلمنا في الفصل الثالث عن الإجرائيات وحالاتها المخلتفة ، وميزنا حالة الإجرائيات
.Current Process من حالة الإجرائية الحالية أو الراهنة Ready Processes الجاهزة للتنفيذ
والجدولة هي عملية اختيار الإجرائية الراهنة بين الإجرائيات القابلة للتنفيذ . وتنبع أهمية الجدولة
من أثرها الكبير على استخدام الموارد وعلى أداء النظام بشكل عام.
تعريف الإجرائية:
هي سلسلة من التعليمات التي تنفذ ضمن سياق تنفيذي معين يعرف باسم حالة الإجرائية . تتضمن
حالة الإجرائية عددًا من المعلومات مثل:
سجلات
مكدس
مساحة من الذاكرة مخصصة للإجرائية
تمر الإجرائية خلال فترة حياتها بعدة حالات للتنفيذ، ويتضمن مخطط الحالات الأبسط حالتي
تنفيذ:
أي أنها مستحوذة على وحدة المعالجة. :Running الإجرائية تعمل
ولكنها لاتعمل: أي أنها غير مستحوذة على وحدة المعالجة. Ready الإجرائية جاهزة للعمل
كانت أغلب أنظمة التشغيل المألوفة لدى المستخدمين خلال سنوات الثمانينات وبداية التسعينات
لاتحوي على خوارزميات جدولة متطورة. ولم يكن بإمكان نظام التشغيل أن DOS, MacOS
يقوم بتشغيل أكثر من إجرائية واحدة، حتى يطلب منه المستخدم الالتفات إلى إجرائ ية أخرى .
على محطات Unix وقد اقتصر استخدام أنظمة التشغيل القادرة على تحقيق جدولة متطورة مثل
العمل والمخدمات المكلفة جدً ا. ولم تبدأ أنظمة التشغيل للحواسيب الشخصية بالتحول نحو
.WindowsNT خوارزميات جدولة متطورة إلا في منتصف التسعينات مع
بتطورات كبيرة في بنيان الحواسيب والإمكانات المتاحة في WindowsNT وترافق ظهور
الحواسيب الشخصية، إذ اقترب أداء الحواسيب الشخصية العادية المتاحة لدى أغلب المتسخدمين
بشكل ملموس من محطات العمل الأكثر تطورًا، وتجاوز بكثير أداء محطات العمل التي كانت
مستخدمة في التسعينات.
2
ظهرت تغيرات في طبيعة التطبيقات إذ انتشرت التطبيقات التي تعتمد تعدد الإجرائيات وتعدد
النياسب، ولاسيما في ضوء انتشار التطبيقات التفاعلية . إذ بات من غير المقبول بالنسبة
للمستخدم ألا يكون قادرًا على تصفح عدة صفحات للوب والتنقل بين صفحة وأخرى بينما ينتهي
من تحميل الصفحات الب طيئة، وربما يكون قد طلب تنزيل عدة ملفات في نفس الوقت، ويجب أن
تتم هذه الأعمال كلها على التوازي وبدون أن يشعر المستخدم بأن هناك تأخيرًا في واحد منها
بسبب الآخر.
تصنيف الإجرائيات
يتميز سلوك الإجرائيات بأنها تعمل عمومًا على شكل رشقات متناوبة من عمليات المعالج ة
والدخل والخرج . إذ تبدأ الإجرائية بتنفيذ عدد من التعليمات (رشقة معالجة ) تليها رشقة من
عمليات الدخل والخرج، ثم تعود إلى العمل من جديد مستخدمة البيانات التي حصلت عليها من
عمليات الدخل والخرج، وهكذا دواليك. ويمكن تصنيف الإجرائيات إلى نوعين :
إجرائيات محدودة بالدخل والخرج: يكون فيها طول رشقات الدخل والخرج أطول من
رشقات عمليات المعالجة.
إجرائيات محدودة بالمعالجة: وهي إجرائيات تحتوي أساسًا على عدد قليل من رشقات
المعالجة الطويلة، وتكون رشقات الدخل والخرج قليلة وقصيرة.
تؤثر عمليات الدخل والخرج كثيرًا على عملية الج دولة، إذ يقوم المجدول تلقائيًا بسحب المعالج
من أية إجرائية تقوم بإجراء عمليات للدخل والخرج وذلك بسبب طول هذه العمليات . فإذا أخذنا
مثا ً لا قراءة حرف من البوابة التسلسلية، فإن هذه العملية تحتاج إلى فترة زمنية تبلغ حوالي 1
م.ثانية، وهذا الوقت يكفي المعالج للقيام بمئات آلاف التعليمات كحد أدنى.
اشتد التباين بين سرعة المعالجات التي تتزايد باطراد حسب قانون مور ، وبين سرعة دارات
الدخل والخرج التي لم تتغير كثيرً ا. فعلى سبيل المثال تمكنت شركة إنتل من ضرب سرعة
بينما لم تزد سرعة الأقراص الصلبة ،Pentium المعالج بأكثر من 50 منذ بداية إنتاج معالجات
بأكثر من ثلاث إلى خمس مرات خلال الفترة نفسها . وبسبب هذا التباين الكبير، لايجوز أن
يترك المعالج منتظرًا لحين انتهاء عملية الدخل والخرج.
متى يحتاج النظام إلى اتخاذ قرار بشأن إجراء جدولة ؟
عندما تنتقل الإجرائية الراهنة إلى حالة الا نتظار، وهناك أسباب عديدة لذلك، كالحاجة
إلى إجراء عمليات دخل وخرج، أو الانتظار لفترة معينة، أو بسبب المزامنة مع إجرائية
أخرى.
3
عندما تنتقل الإجرائية الراهنة إلى حالة القابلة للتنفيذ، كما يحصل بعد تنفيذ مقاطعة
الميقاتية التي تخبر الإجرائية الراهنة بانتهاء شري حتها الزمنية في نظام تشغيل يعمل بمبدأ
التشارك بالوقت.
عندما تنتقل إجرائية من حالة الانتظار إلى حالة القابلة للتنفيذ، كما يحدث عندما تنتهي
عملية الدخل والخرج التي كانت تقوم بتنفيذها.
2. خوارزميات الجدولة
معايير تقييم الخوارزميات
هناك العديد من المعايير الممكنة:
يجب المحافظة على ارتفاع نسبة استخدام :CPU utilization نسبة استخدام المعالج
المعالج قدر الإمكان، والمقصود بذلك الحد من الفترة التي يقضيها المعالج دون تنفيذ تعليمات
الإجرائيات.
.Throughput زيادة عدد الإجرائيات التي تنهي تنفيذها خلال وحدة الزمن
اختصار زم ن تنفيذ الإجرائية، وهو الزمن الفاصل بين طلب التنفيذ وانتهائه
.Turnaround time
وهو الزمن الفاصل بين تقديم طلب إلى :Response Time اختصار زمن الاستجابة
المعالج والحصول على اول جواب منه.
وهو الزمن الذي تقضيه الإجرائية منتظرة ف ي :Waiting time اختصار زمن الانتظار
رتل الإجرائيات الجاهزة . وهو مقياس أفضل لأداء المجدول من زمن التنفيذ، إذ أن الأخير
يشمل زمن انتظار الدخل والخرج الذي لا علاقة للمجدول به.
وهي نسبة الزمن اللازم لتنفيذ الإجرائية :Penalty time اختصار نسبة التردي
بالمقارنة مع الزمن الذي كانت الإجرائية ستحتاجه في بيئة مثالية.
رفع فاعلية المجدول، وذلك لأن الزمن اللازم للجدولة يمثل كلفة إضافية ومتكررة نظرًا
لتواتر هذه العملية.
FCFS (First-Come, First-Served) خوارزمية الجدولة بحسب ترتيب الوصول
وهي أبسط الخوارزميات : يختار المجدول الإجرائية التي في رأس الرتل، وتدخ ل الإجرائيات
الجديدة الرتل في نهايته . لاتتخلى الإجرائية عن المعالج حتى انتهائها، أو عند قيامها بعمليات
دخل خرج.
4
لنفترض وجود الإجرائيات الأربع التالية مع أزمان التشغيل الموافقة لها :
P3 P2 P الإجرائية 1
3 3 الزمن 24
يكون معايير التقييم على الشكل p1p2p في حال تنفيذ الإجرائيات بحسب الترتيب : 3
التالي:
17 ثانية = (24 + 27) / زمن الانتظار الوسطي : 3
17 ثانية =(30+24+27)/ زمن التنفيذ الوسطي : 3
تدفق الإجرائيات : 6 إجرائيات/دقيقة.
ستكون المع ايير على الشكل p1p3p وفي حال تنفيذ الإجرائيات بحسب الترتيب : 2
التالي:
زمن الانتظار الوسطي : 6 ثانية
زمن التنفيذ الوسطي : 13 ثانية
تدفق الإجرائيات : 6 إجرائيات/دقيقة.
ونستنتج من ذلك أن تغييرًا طفيفًا في الترتيب أدى إلى اختلاف كبير في النتائج من مرتبة
.100%
تعاني هذه الإجرائية من مشكلة أداء في حال وجود تمايز كبير بين الإجرائيات . فلو كانت عندنا
إجرائية محدودة بالمعالجة، ويليها عدد من الإجرائيات المحدودة بالدخل والخرج، ستقضي تلك
الأخيرة معظم وقتها منتظرة انتهاء الإجرائية من المعالج . ولتأكيد هذه النقطة، نأخذ مثا ً لا ثانيًا لا
تصل فيه الإجرائيات في نفس الوقت :
Shortest Job First (SJF) خوارزمية الجدولة بحسب الأقصر أو ً لا
يتلخص مبدأ عمله هذه الخوارزمية في حساب طول رشقة التنفيذ القادمة لكل إجرائية، وتسليم
المعالج للإجرائية ذات أقصر رشقة تنفيذ . وإذا تساوى الزمن لدى إجرائيتين، نأخذ الأولى في
الترتيب الزمني.
إذا طبقنا الخوارزمية على المثال السابق، فإننا نحصل على النتيجة التالية :
P1 P2 P3
P1 P3 P2
5
ويظهر المخطط التالي عملية الجدولة للإجرائيات المذكورة :
لو حسبنا معايير أداء الخوارزمية في هذه الحالة، سنحصل على الجدول التالي :
ونسنتنج من هذا الجدول وجود تباطؤ كبير في الإجرائيات التي يكون زمن تنفيذها
لديها نسبة تباطؤ هي % 3.5 ، ويمكن أن يكون الرقم أسوأ بكثير ،P قصيرًا، فالإجرائية 3
عند وجود إجرائيات طويلة تعيق تنفيذ الإجرائيات التي تليها.
إن هذه الخوارزمية تناسب إذًا الإجرائيات التي يكون زمن تنفيذها طوي ً لا، أي أنها
محدودة بالمعالجة وليس بالدخل والخرج . وهو تمامًا عكس ما يفضل أن تكون عليه
خوارزميات الجدولة، إذ أن أغلب التطبيقات التفاعلية والتي تتعاطي مباشرة مع المستخدم
هي من النوع المحدود بالدخل والخرج.
وربما كانت الميزة الحقيقة الوحيدة في هذه الخوارزمية هي عدم وجود مجاعة، إذ
ستحصل كل إجرائية على المعالج إذا انتظرت دورها.
ونلاحظ هنا انخفاضا كبيرًا في زمن الانتظار وفي نسبة التباطؤ بالمقارنة مع الخوارزمية
الأولى. ويمكن إثبات أن هذه الخوارزمية تعطي زمن الا نتظار الوسطي الأصغر بين كل
خوارزميات الجدولة.
النقطة الأصعب هنا تكمن في حساب طول رشقة التنفيذ . ففي حالة الجدولة بعيدة الأمد، وهي
التي تستخدم في نظام يعمل بمبدأ الدفعات، يطلب من المستخدم إعطاء تصور عن الزمن . وإذا
كانت القيمة المعطاة اقل بكثير من الرقم الحقي قي، يوقف نظام التشغيل عمل الإجرائية . أما في
حالة الجدولة قصيرة الأمد، فنعتمد على أطوال الرشقات السابقة لنتوقع الرشقات القادمة . ويتم
6
استخدام خوارزمية معيارية لحساب وسطي أطوال الرشقات السابقة.
فعلينا ،n هو الطول المتوقع للرشقة Sn و ،n هو الطول المقاس الرشقة رقم Tn فإذا افترضنا أن
قيمته بين الصفر والواحد ونستخدم المعادلة التالية : w اختيار معامل تثقيل
الأهمية النسبية للماضي والحاضر، فإذا كانت القيمة 0.5 ، نكون قد أعطينا أهمية w تحدد قيمة
للرشقة الأخيرة تعادلة سابقاتها، أما إذا كانت 1، فهذا يعني أننا لانهتم إلا بالرشقة الأخيرة.
لدى وصول إجرائية زمن تنفيذ رشقتها أقصر مما تبقى من زمن رشقة الإجرائية الراهنة،
يختلف عمل المجدول في حال إذا كان شفعيًا أو غير شفعي.
شفعي: تستبدل الإجرائية الراهنة ويعطى المعالج للإجرائية الوافدة.
غير شفعي: فسيترك الإجرائية الراهنة تتابع التنفيذ حتى تنهي رشقتها ثم تتخلى طوعًا
Shortest عن المعالج للإجرائية الوافدة. وتعرف الحالة الشفعية باسم
.remaining time first
الجدولة بتقاسم الزمن
هذه الخوارزمية موجهة لمستخدمي الأنظمة التي تعمل بتقاسم الزمن، وهدفها الأساسي هو رفع
درجة التفاعلية للمستخدمين مع النظام وإعطاؤهم الانطباع بأن ك ً لا منهم يمتلك الحاسوب لوحده.
تشبه هذه الخوارزمية تلك التي تعتمد مبدأ الترتيب الزمني، مع الفرق بأن هذه الخوارزمية
وتحصل ،Time Slice تضيف مفهوم التبديل الشفعي. بحيث تخصص لكل إجرائية شريحة زمنية
الإجرائيات على المعالج بحسب ت رتيب وصولها، ولكن لفترة زمنية تعادل الشريحة الزمنية،
للتخلى عن المعالج بعدها وتعود للانتظار في نهاية رتل الإجرائيات الجاهزة.
يحتاج تنفيذ هذه الخوارزمية إلى تفعيل المقاطعات الواردة من الميقاتية، فعندما نقوم بتخصيص
إجرائية بالمعالج، نطلب من الميقاتية أن ترسل مقاطعة بعد انتهاء فترة الشريحة الزمنية.
في هذه الخوارزمية يمكن أن يحصل تبديل السياق إذا لأحد سببين:
) انتهاء الشريحة الزمنية للإجرائية الحالية
) قيام الإجرائية بتنفيذ عملية ينتج عنها توقف مثل طلب دخل/خرج، أو حجز سيمافور.
يظهر الشكل التالي عملية الجدولة بتقاسم الزمن في مثالنا المتكرر، ونفترض أن كافة الإجرائيات
بدأت في نفس الوقت.
Sn+1= wTn+ (1-w)Sn
7
زمن
التنفيذ
زمن
الوصول
الإجرائية
3 0 P1
5 1 P2
2 3 P3
5 9 P4
5 12 P5
تؤدي هذه الخوارزمية إلى تنفيذ عدد كبير من عمليات تبديل السياق، وتبرز هنا ضرورة كون هذا
الزمن أمثليًا وهذا أحد الأسباب الأس اسية للانتقال إلى نموذج النياسب . يقترب أداء الخوارزمية من
كلما أطلنا الشريحة الزمنية. FCFS أداء
الجدولة بالأولوية
تناط بكل إجرائية أولوية ما، ويقوم المجدول بتخصيص المعالج للإجرائية ذات الأولوية الأعلى،
إحدى SJF وفي ح ال تساوي الأولويات يعتمد مبدأ الترتيب الزمني . ويمكن اعتبار خوارزمية
حالات الجدولة بالأولوية بحيث تكون الأولوية هي طول رشقة التنفيذ، وتتغير الأولوية مع الزمن
بفضل خوارزمية حساب الوسطي التي عرضناها.
8
وهي أكثر الحالات ،Static عندما تكون الأولوية رقمًا مثبًا، تعرف هذه الحالة بالأولوية الساكنة
شيوعًا. وتعاني من مشكلة المجاعة، إذ لن تحصل الإجرائيات ذات الأولوية المنخفضة على
المعالج في وقت مقبول.
وفي أنظمة الزمن الحقيقي التي تعتمد كثيرًا على الجدولة بالأولوية، فإن هذا يشكل مشكلة كبيرة
لأنه قد يؤدي إلى تأ خر الإجرائية عن زمنها الحدي وعدم تمكنها من أداء العمل المطلوب في
الوقت اللازم.
لرفع أولوية الإجرائيات الجاهزة Aging تعتمد خوازميات الجدولة بالأولوية على مفهوم التقادم
والتي تبقى منتظرة في الرتل دون الجصول على المعالج . وفي هذه الحالة تقسم الأولوية إلى
جزئين:
جزء ثابت: يحدد لدى إنشاء الإجرائية.
جزء متغير: يتغير بحسب التقادم.
وتكون الأولوية الفعلية للإجرائية هي مجموع الرقمين . ويتم رفع الجزء المتغير لكافة
الإجرائيات المنتظرة في الرتل بعد كل عملية تبديل سياق، ويعاد تأسيس الجزء المتغير بعد
تخصيص الإجرائية المنتظرة بالمعالج.
الجدولة متعددة المستويات
وهي تشبه الجدولة بتقاسم الزمن وتختلف عنها بأنها لاتعتمد على رتل واحد للإجرائيات الجاهزة
وإنما على أرتال عدة، ويدار كل من هذه الأرتال بطريقة مختلفة عن الرتل الآخر . مثال على
ذلك هو الفصل بين الإجرائيات التفاعلية والإ جرائيات غير التفاعلية، ويقوم المجدول بالجدولة
على مستوين:
) المستوى الأول : هو بين الأرتال، إذ يخصص المجدول شريحة زمنية لكل من الأرتال
تتناسب مع طبيعة وعدد الإجرائيات ضمنه، كأن يخصص % 80 من زمن المعالج لصالح
رتل الإجرائيات التفاعلية و% 20 للإجرائيات غير التفاعلية.
) المستوى الثاني : هو داخل كل رتل، بحيث يقوم المجدول بإدارة كل رتل باستخدام
خوارزمية مختلفة تتناسب مع طبيعة الإجرائيات ضمنه . فيدار رتل الإجرائيات التفاعلية
باستخدام خوارزمية تقاسم الزمن، أما رتل الإجرائيات غير التفاعلية فيدار باستخدام
خوارزمية الترتيب الزمني وبدون تبديل شفعي.
9
يمكن أن تسمح الجدولة بنقل الإجرائية من رتل لآخر وذلك لإعطاء الإجرائيات التي تحتاج إلى
الكثير من عمليات الدخل والخرج وهي أقرب إلى التفاعلية، أولوية بالمقارنة مع الإجرائيات
التي تقوم بعمليات حساب كثيفة وغير تفاعلية.
ولتوضيح الفكرة نورد المثال التالي :
يخصص المجدول ثلاثة أرتال للجدولة ارقامها 0 و 1 و 2، ويكون الرتل رقم 0 الأعلى
أولوية. ولاتنفذ الإجرائيات في رتل ما إلا عندما يكون الرتل الأعلى أولوية فارغًا
، تبدأ الإجرائية عملها في الرتل رقم 0
ويخصص لها حصة زمنية مقدارها 8
م.ثا، فإذا استهلكتها كلها د ون القيام
بعمليات دخل /خرج، تنقل إلى الرتل رقم
.1
، عند تنفيذ إجرائية من الرتل رقم 1
تخصص لها حصة زمنية مقدارها 16
م.ثا، فإذا استهلكتها تنقل إلى الرتل رقم 2
يدار الرتل رقم 2 باستخدام خوارزمية
تقاسم الوقت مع حصة زمنية عالية، أو
باستخدام خوارزمية الترتيب الزمني.
10
وسنعطي هنا شرحًا تقريبيًا للخوارزمية : :UNIX مثال آخر الجدولة في نظام
تخصص الإجرائية بأولوية مقدارها 60 لدى بداية عملها حيث الأولوية تابع متناقص.
تولد ميقاتية النظام مقاطعة بدور يتراوح بين 10 و 20 م .ثا، ونفترض أنه سيكون لدي نا
60 مقاطعة في الثانية.
،CPU usage " تحتوي كتلة التحكم بالإجرائية على حقل يدعى "استخدام المعالج
ويضاف 1 إلى هذا الحقل في كل مرة تقاطع فيها الإجرائية.
يختار النظام دومًا الإجرائية ذات الأولوية الأعلى لتخصيصها بالمعالج، وفي حال
وجود تساوي في الأولويات، يختار الإجرائية التي مر عليها زمن أطول.
يقوم نظام التشغيل بتعديل الأولوية واستخدام المعالج دوريًا (مرة في الثانية ) بحسب
الصيغة التالية :
1) استخدام المعالج = استخدام المعالج/ 2
( 2) الأولوية = الأولوية الأساسية + (استخدام المعالج/ 2
أي أن الإجرائية التي لم تستخدم وحدة ا لمعالجة كثيرًا مؤخرًا تحصل على أولوية
أعلى، وبذلك تكون أولوية الإجرائيات التي تكثر من عمليات الدخل والخرج والإجرائيات
التفاعلية أعلى من أولوية الإجرائيات التي تكثر من استخدام وحدة المعالجة . وهو ما يحسن
من زمن استجابة التطبيقات التفاعلية ويعطي الراحة لمستخدمي هذه التطبيقات.
لطيف !!)، ) nice يسمح النظام للمستخدم بتخفيض أولوية إجرائية باستخدام تعليمة
والتي تسمح بزيادة قيمة ثابتة إلى أولوية الإجرائية في كل تعديل دوري لتصبح الصيغة :
الأولوية = الأولوية الأساسية + استخدام المعالج/ 2 + تخفيض الأولوية.
يمكن للمستخدم بذلك تخفيض أولوية الإجرائيات التي لايراها مهمة وذلك لإفادة
الإجرائيات الأخرى (بما فيها تلك الخاصة به).
نهاية الوحدة