الفصل ٤: الخيوط

CS330 - أنظمة التشغيل

نماذج الخيوط المتعددة، الفوائد، والتطبيق

٤.١ نظرة عامة على الخيوط

الخيط هو وحدة أساسية لاستغلال المعالج. ويسمى أيضًا عملية خفيفة الوزن. يتكون الخيط من معرف الخيط، عداد البرنامج، مجموعة المسجلات، والمكدس.

مكونات الخيط

كل خيط له خاصته:

  • معرف الخيط
  • عداد البرنامج
  • مجموعة المسجلات
  • مساحة المكدس

الخيوط تشارك مع الخيوط الأخرى:

  • قسم الكود
  • قسم البيانات
  • موارد نظام التشغيل (الملفات المفتوحة، الإشارات)

أنواع العمليات

النوع الوصف الخصائص
عملية ثقيلة الوزن عملية تقليدية بخيط واحد مسار تحكم واحد
عملية خفيفة الوزن اسم آخر للخيط وحدة أساسية لاستغلال المعالج
عملية متعددة الخيوط عملية بخيوط متعددة خيوط متعددة تشارك موارد العملية

📊 عملية أحادية الخيط مقابل متعددة الخيوط

[إدراج مخطط يوضح هيكل عملية أحادية الخيط مقابل متعددة الخيوط]

٤.٢ العمليات أحادية الخيط مقابل متعددة الخيوط

عملية أحادية الخيط
الموارد المشتركة:
  • الكود
  • البيانات
  • الملفات
لكل عملية:
  • المسجلات
  • المكدس
  • عداد البرنامج
عملية متعددة الخيوط
مشترك (بين الخيوط):
  • الكود
  • البيانات
  • الملفات
لكل خيط:
  • المسجلات
  • المكدس
  • عداد البرنامج

⚠️ مهم:

الخيوط داخل نفس العملية تشارك الذاكرة والموارد، مما يجعل التواصل بين الخيوط فعالاً ولكنه يتطلب مزامنة دقيقة لتجنب حالات السباق.

٤.٣ فوائد تعدد الخيوط

📱 الاستجابة

تسمح للبرنامج بالاستمرار في العمل حتى لو كان جزء منه محجوبًا. مثال: متصفح الويب يسمح بتفاعل المستخدم في خيط بينما يتم تحميل الصور في خيط آخر.

🔄 مشاركة الموارد

الخيوط تشارك الذاكرة والموارد للعملية التي تنتمي إليها. أسهل من الذاكرة المشتركة أو تمرير الرسائل بين العمليات.

💰 الاقتصاد

إنشاء الخيوط أسرع من إنشاء العمليات. تبديل السياق بين الخيوط له عبء أقل. في Solaris، إنشاء عملية أبطأ ٣٠ مرة من إنشاء خيط.

⚡ قابلية التوسع

يمكن الاستفادة من معماريات متعددة المعالجات. خيوط متعددة يمكن أن تعمل بالتوازي على وحدات معالجة مختلفة. عملية أحادية الخيط يمكن أن تعمل فقط على معالج واحد.

📝 سؤال اختبار (CS330):

س: اذكر الفوائد الأربع الرئيسية للبرمجة متعددة الخيوط.

الإجابة:

  1. الاستجابة: قد تسمح بالاستمرار في التنفيذ إذا كان جزء من العملية محجوبًا
  2. مشاركة الموارد: الخيوط تشارك موارد العملية، أسهل من الذاكرة المشتركة
  3. الاقتصاد: أرخص من إنشاء العمليات، عبء أقل لتبديل السياق
  4. قابلية التوسع: العملية يمكن أن تستفيد من معماريات متعددة المعالجات

٤.٤ البرمجة متعددة النوى

التزامن مقابل التوازي

نظام أحادي النواة (التزامن)

نواة واحدة
T₁
T₂
T₃
T₄
T₁
T₂
T₃
T₄

الخيوط متداخلة عبر الزمن

نظام متعدد النوى (التوازي)

النواة ١
T₁
T₃
T₁
T₃
النواة ٢
T₂
T₄
T₂
T₄

الخيوط تعمل في وقت واحد على نوى مختلفة

الجانب التزامن التوازي
التعريف مهام متعددة تتقدم مهام متعددة تُنفذ في وقت واحد
العتاد يمكن العمل على نواة واحدة يحتاج نوى متعددة
التنفيذ تنفيذ متداخل تنفيذ متزامن

أنواع التوازي

توازي البيانات

يوزع مجموعات فرعية من نفس البيانات عبر نوى متعددة، نفس العملية على كل مجموعة.

مثال: جمع عناصر مصفوفة - تقسيم المصفوفة إلى أجزاء، جمع كل جزء بالتوازي.

توازي المهام

توزيع الخيوط عبر النوى، كل خيط يقوم بعملية فريدة.

مثال: خادم ويب - خيط يتعامل مع الطلبات، آخر يعالج البيانات، آخر يحدّث السجلات.

٤.٥ خيوط المستخدم وخيوط النواة

خيوط المستخدم

خيوط تُدار بواسطة مكتبة خيوط على مستوى المستخدم، وليس في النواة. تُجدول بواسطة مكتبة الخيوط.

المزايا العيوب
  • سريعة في الإنشاء والإدارة
  • لا تحتاج تدخل من النواة
  • تبديل الخيط لا يتطلب وضع النواة
  • استدعاء نظام محجوب يحجب العملية بأكملها
  • لا يمكن الاستفادة من المعالجة المتعددة
  • لا توازي حقيقي

أمثلة: POSIX Pthreads, Java threads, Win32 threads

خيوط النواة

كل إدارة الخيوط تتم بواسطة النواة نفسها. النواة تقوم بالإنشاء والجدولة والإدارة.

المزايا العيوب
  • إذا انحجب خيط، يمكن للنواة جدولة آخر
  • يمكن تشغيل الخيوط على معالجات مختلفة
  • توازي حقيقي على أنظمة متعددة المعالجات
  • أبطأ في الإنشاء والإدارة
  • يحتاج تدخل من النواة
  • عبء أكبر لعمليات الخيوط

أمثلة: ويندوز، لينكس، ماك أو إس، iOS، أندرويد

📝 سؤال تطبيقي:

س: أحد عيوب خيوط المستخدم مقارنة بخيوط النواة هو:

  • أ) الجدولة خاصة بالتطبيق
  • ب) عندما ينفذ خيط مستخدم استدعاء نظام، كل الخيوط في العملية تُحجب
  • ج) تبديل الخيط لا يتطلب صلاحيات وضع النواة
  • د) كل ما ذكر

٤.٦ نماذج تعدد الخيوط

١. نموذج متعدد إلى واحد

مساحة المستخدم
مساحة النواة

الخصائص:

  • خيوط مستخدم متعددة تُربط بخيط نواة واحد
  • إدارة الخيوط في مساحة المستخدم - فعالة
  • العملية بأكملها تُحجب إذا نفذ خيط استدعاء نظام محجوب
  • لا يمكن أن تعمل بالتوازي على معالجات متعددة
  • قلة من الأنظمة تستخدم هذا النموذج حاليًا

أمثلة: Solaris Green Threads, GNU Portable Threads

٢. نموذج واحد إلى واحد

مساحة المستخدم
↓ ↓ ↓
مساحة النواة

الخصائص:

  • كل خيط مستخدم يُربط بخيط نواة
  • توازٍ أكبر - إذا انحجب واحد، يمكن للآخرين العمل
  • يمكن أن تعمل على وحدات معالجة مختلفة في نظام متعدد المعالجات
  • إدارة الخيوط بواسطة النواة - أبطأ
  • عبء إنشاء خيوط النواة

أمثلة: ويندوز، لينكس

٣. نموذج متعدد إلى متعدد

مساحة المستخدم
↘ ↓ ↙
مساحة النواة

الخصائص:

  • خيوط مستخدم متعددة تُربط بعدد أقل أو مساوٍ من خيوط النواة
  • يسمح بخيوط مستخدم أكثر من خيوط النواة
  • خيوط النواة تعمل بالتوازي على معالج متعدد
  • إذا انحجب خيط، يمكن للنواة جدولة آخر
  • أفضل ميزات كلا النموذجين

أمثلة: Solaris قبل الإصدار ٩، ويندوز مع ThreadFiber

٤. نموذج ثنائي المستوى

مشابه لـ M:M، لكنه يسمح بربط خيط مستخدم بخيط نواة.

أمثلة: IRIX, HP-UX, Tru64 UNIX, Solaris ٨ والإصدارات الأقدم

٤.٧ مكتبات الخيوط

مكتبة الخيوط توفر للمبرمج واجهة برمجة لإنشاء وإدارة الخيوط.

POSIX Pthreads

  • معيار POSIX (IEEE 1003.1c)
  • مواصفة، وليس تطبيقًا
  • شائعة في أنظمة يونكس
  • يمكن أن تكون على مستوى المستخدم أو النواة

Java Threads

  • تُدار بواسطة JVM
  • مستقلة عن النظام
  • عادةً تُربط بخيوط نظام التشغيل
  • مضمنة في اللغة

Windows Threads

  • واجهة Win32/64 API
  • مكتبة على مستوى النواة
  • نموذج واحد إلى واحد
  • دالة CreateThread()

مثال Pthreads

// مثال بسيط لـ Pthread في لغة C #include <pthread.h> #include <stdio.h> #include <stdlib.h> void *runner(void *param) { int *value = (int *)param; printf("الخيط: القيمة = %d\n", *value); *value = (*value) * 2; pthread_exit(0); } int main() { pthread_t tid; // معرف الخيط pthread_attr_t attr; // سمات الخيط int value = 5; // تهيئة السمات الافتراضية pthread_attr_init(&attr); // إنشاء خيط pthread_create(&tid, &attr, runner, &value); // انتظار خروج الخيط pthread_join(tid, NULL); printf("الرئيسي: القيمة = %d\n", value); return 0; }

دوال Pthread الشائعة

الدالة الوصف
pthread_create() إنشاء خيط جديد
pthread_join() انتظار إنهاء الخيط
pthread_exit() إنهاء الخيط الحالي
pthread_attr_init() تهيئة سمات الخيط
pthread_self() الحصول على معرف الخيط الحالي
pthread_equal() مقارنة معرفي خيطين

٤.٨ قضايا الخيوط

١. دلالات fork() و exec()

عندما تستدعي عملية متعددة الخيوط fork():

  • هل يجب على العملية الجديدة نسخ كل الخيوط؟
  • أو فقط الخيط المستدعي؟

الأنظمة المختلفة تتعامل مع هذا بشكل مختلف. exec() عادةً تستبدل العملية بأكملها.

٢. معالجة الإشارات

أين يجب تسليم الإشارة؟

  • إلى الخيط الذي تنطبق عليه الإشارة
  • إلى كل خيط في العملية
  • إلى خيوط معينة في العملية
  • إلى خيط محدد مخصص لاستقبال كل الإشارات

٣. إلغاء الخيط

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

٤. تخزين محلي للخيط

يسمح لكل خيط بأن يكون له نسخته الخاصة من البيانات. مفيد عندما لا تتحكم في عملية إنشاء الخيط.

٥. تجمعات الخيوط

المفهوم:

إنشاء عدد من الخيوط عند بدء التشغيل ووضعها في تجمع حيث تنتظر العمل.

المزايا:

  • عادةً أسرع قليلاً لخدمة الطلب بخيط موجود
  • يسمح بتحديد عدد الخيوط في التطبيق
  • يفصل المهمة التي يجب أداؤها عن إدارة الخيوط

٤.٩ هيكل الخادم متعدد الخيوط

عميل
خادم
(خيط رئيسي)
خيط عامل

كيف يعمل:

  1. الخادم ينشئ خيطًا منفصلاً يستمع لطلبات العملاء
  2. عند وصول طلب، ينشئ الخادم خيطًا جديدًا لخدمة الطلب
  3. الخادم يستأنف الاستماع لطلبات إضافية
  4. أكثر كفاءة من إنشاء عملية جديدة لكل طلب

مثال: خادم ويب

  • الخيط الرئيسي يستمع على المنفذ ٨٠
  • لكل طلب HTTP، يتم إنشاء خيط عامل
  • الخيط العامل يتعامل مع الطلب ويرسل الرد
  • الخيط الرئيسي يستمر في قبول اتصالات جديدة

٤.١٠ أسئلة تطبيقية على طريقة الاختبارات

أسئلة اختيار من متعدد

س١. أي مما يلي لا تشاركه الخيوط؟

  • أ) عداد البرنامج
  • ب) المكدس
  • ج) كل من (أ) و (ب)
  • د) لا شيء مما ذكر

س٢. عملية لها مسارات تحكم متعددة يمكنها أداء أكثر من مهمة في وقت واحد. هذا يسمى:

  • أ) تعدد البرمجة
  • ب) تعدد الخيوط
  • ج) تعدد المعالجة
  • د) تعدد المهام

س٣. في نموذج الخيوط متعدد إلى واحد، إذا نفذ خيط استدعاء نظام محجوب:

  • أ) فقط ذلك الخيط يُحجب
  • ب) العملية بأكملها تُحجب
  • ج) يتم جدولة خيط آخر
  • د) النواة تتحول إلى عملية أخرى

س٤. إنشاء الخيط هو:

  • أ) أكثر تكلفة من إنشاء العملية
  • ب) أقل تكلفة من إنشاء العملية
  • ج) متساوٍ في التكلفة مع إنشاء العملية
  • د) غير ممكن في أنظمة التشغيل الحديثة

أسئلة إجابة قصيرة

س٥. تأمل مقطع الكود هذا. كم عدد العمليات والخيوط الفريدة التي تم إنشاؤها؟

pid = fork(); if (pid == 0) { /* العملية الابنة */ fork(); thread_create(...); } fork();

الإجابة:

  • fork() الأولى تنشئ ابنًا واحدًا (عمليتان إجمالاً)
  • الابنة تنفذ fork() ثانية (٣ عمليات إجمالاً)
  • عمليتان تنفذان thread_create() (خيطان تم إنشاؤهما)
  • كل الـ ٣ عمليات تنفذ fork() النهائية (٦ عمليات إجمالاً)
  • الإجمالي: ٦ عمليات، ٨ خيوط (٦ رئيسية + ٢ منشأة)

س٦. في نظام متعدد المعالجات بنموذج خيوط متعدد إلى متعدد، ناقش الأداء عندما:

أ) عدد خيوط النواة < عدد المعالجات

ب) عدد خيوط النواة = عدد المعالجات

الإجابة:

أ) بعض المعالجات تبقى خاملة لأن الجدول يربط خيوط النواة فقط بالمعالجات، وليس خيوط المستخدم.

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

س٧. ما الفرق بين التزامن والتوازي؟

الإجابة:

  • التزامن: مهام متعددة تتقدم، ربما متداخلة. يمكن أن يحدث على معالج واحد من خلال تقاسم الوقت.
  • التوازي: مهام متعددة تُنفذ في وقت واحد. يحتاج معالجات/نوى متعددة.

٤.١١ المصطلحات الرئيسية والتعريفات

المصطلح التعريف
خيط وحدة أساسية لاستغلال المعالج؛ عملية خفيفة الوزن
تعدد الخيوط قدرة نظام التشغيل على دعم خيوط متعددة في عملية واحدة
خيط مستخدم خيط يُدار بواسطة مكتبة على مستوى المستخدم بدون دعم النواة
خيط نواة خيط يُدار مباشرة بواسطة نواة نظام التشغيل
تجمع خيوط مجموعة من الخيوط المنشأة مسبقًا تنتظر العمل
TLS تخزين محلي للخيط - تخزين بيانات لكل خيط
pthread مواصفة مكتبة خيوط POSIX
التزامن مهام متعددة تتقدم (ربما متداخلة)
التوازي مهام متعددة تُنفذ في وقت واحد
حالة السباق عندما تعتمد النتيجة على توقيت أحداث غير متحكم فيها

٤.١٢ مخططات من الشرائح

📊 عملية أحادية الخيط مقابل متعددة الخيوط

[إدراج مخطط من Chapter_4.pdf صفحة ٦]

📊 خيوط المستخدم وخيوط النواة

[إدراج مخطط يوضح فصل مساحة المستخدم/النواة]

📊 هيكل خادم متعدد الخيوط

[إدراج مخطط هيكل الخادم من الشرائح]

📊 مقارنة نماذج الخيوط

[إدراج نماذج متعدد إلى واحد، واحد إلى واحد، متعدد إلى متعدد]

ملاحظة: يرجى توفير المخططات الفعلية من شرائح Chapter_4.pdf لاستبدال هذه العناصر النائبة.