Deep Dive: Synchronization Examples تعمق: أمثلة المزامنة
Applying Semaphores and Locks to the "Big Three" classical problems: Bounded Buffer, Readers-Writers, and Dining Philosophers. تطبيق Semaphores و Locks على المشاكل الكلاسيكية الثلاث الكبرى: Bounded Buffer، Readers-Writers، و Dining Philosophers.
1. Bounded Buffer Problem 1. مشكلة المخزن المؤقت المحدود (Bounded Buffer Problem)
Also known as the Producer-Consumer problem.
Goal: Producers create items, Consumers eat them. Buffer has fixed size $N$.
Constraints: Producer must wait if full. Consumer must wait if empty.
تعرف أيضاً بمشكلة المنتج-المستهلك.
الهدف: المنتجون ينشئون العناصر، والمستهلكون يأكلونها. المخزن المؤقت له حجم ثابت $N$.
القيود: يجب على المنتج الانتظار إذا كان المخزن ممتلئاً. يجب على المستهلك الانتظار إذا كان المخزن فارغاً.
Semaphore full = 0; // Count of filled slots
Semaphore empty = N; // Count of empty slots
2. Readers-Writers Problem 2. مشكلة القراء والكتاب (Readers-Writers Problem)
First Readers-Writers Problem مشكلة القراء والكتاب الأولى
Allows multiple readers to read at the same time. Only one writer can write at a time.
Priority: Readers. No reader is kept waiting unless a writer has already obtained permission. (Writers may starve).
تسمح لعدة قراء بالقراءة في نفس الوقت. كاتب واحد فقط يمكنه الكتابة في وقت واحد.
الأولوية: للقراء. لا يتم جعل القارئ ينتظر ما لم يكن الكاتب قد حصل بالفعل على الإذن. (قد يحدث Starvation للكتاب).
Semaphore mutex = 1; // Protects read_count
int read_count = 0;
3. Dining Philosophers Problem 3. مشكلة الفلاسفة المتناولين للطعام (Dining Philosophers Problem)
The Setup الإعداد
5 Philosophers sit at a round table. 5 Chopsticks placed between them.
To eat, a philosopher needs 2 chopsticks (Left and Right).
Shared data: `Semaphore chopstick[5];` (Initialized to 1).
5 فلاسفة يجلسون على طاولة مستديرة. 5 عيدان طعام موضوعة بينهم.
لكي يأكل، يحتاج الفيلسوف إلى عودين (يمين ويسار).
البيانات المشتركة: `Semaphore chopstick[5];` (مهيأة بـ 1).
- Allow at most 4 philosophers at the table.السماح بحد أقصى 4 فلاسفة على الطاولة.
- Pick up chopsticks only if BOTH are available (Atomic check).التقاط العيدان فقط إذا كان كلاهما متاحاً (فحص ذري).
- Asymmetric solution: Odd philosophers pick Left first, Even pick Right first.حل غير متماثل: الفلاسفة الفرديون يلتقطون اليسار أولاً، والزوجيون يلتقطون اليمين أولاً.
Real World: Windows العالم الحقيقي: Windows
Windows uses interrupt masks for uniprocessor systems and spinlocks for multiprocessor systems. يستخدم Windows أقنعة المقاطعة للأنظمة أحادية المعالج و Spinlocks للأنظمة متعددة المعالجات.
The Exam Vault خزنة الاختبار
Professor's Secrets & Trap Avoidance أسرار البروفيسور وتجنب الفخاخ
TRAP: Reader-Writer Starvation فخ: Starvation للقراء والكتاب
The "First Readers-Writers Problem" solves mutual exclusion but suffers from Writer Starvation. If new readers keep arriving, the writer will wait forever because `read_count` never drops to 0. "مشكلة القراء والكتاب الأولى" تحل الاستبعاد المتبادل ولكنها تعاني من Writer Starvation. إذا استمر القراء الجدد في الوصول، سينتظر الكاتب إلى الأبد لأن `read_count` لن ينخفض أبداً إلى 0.
TRAP: Signal & Wait Order فخ: ترتيب Signal و Wait
In Bounded Buffer, swapping `wait(empty)` and `wait(mutex)` can cause Deadlock.
If Producer grabs mutex (lock) but buffer is full (`empty` is 0), it sleeps holding the lock. Consumer cannot grab lock to empty the buffer. System freezes.
في Bounded Buffer، تبديل `wait(empty)` و `wait(mutex)` يمكن أن يسبب Deadlock.
إذا أمسك المنتج بالـ mutex (القفل) لكن المخزن ممتلئ (`empty` هو 0)، فسينام وهو يمسك بالقفل. لا يستطيع المستهلك أخذ القفل لتفريغ المخزن. يتجمد النظام.
SECRET: Monitor Pattern سر: نمط Monitor
While Semaphores are powerful, they are error-prone (easy to forget a signal). High-level languages (Java/C#) use Monitors (synchronized keyword), which automatically handle locking and unlocking scope-wise. بينما الـ Semaphores قوية، فهي عرضة للأخطاء (من السهل نسيان إشارة). اللغات عالية المستوى (Java/C#) تستخدم Monitors (الكلمة المفتاحية synchronized)، التي تعالج القفل وفتحه تلقائياً حسب النطاق.
KEY CONCEPT: Condition Variable مفهوم أساسي: Condition Variable
In Monitors, we use Condition Variables (`wait()`, `signal()`) not to lock, but to wait for a specific condition (e.g., "Buffer Not Empty"). Note: Monitor `signal` is different from Semaphore `signal`. في Monitors، نستخدم Condition Variables (`wait()`، `signal()`) ليس للقفل، ولكن للانتظار حتى يتحقق شرط معين (مثل "المخزن ليس فارغاً"). ملاحظة: `signal` في Monitor تختلف عن `signal` في Semaphore.