Foundationপ্রথম নীতি থেকে
LEVEL 4 · Operating Systems

Condition Variable

কন্ডিশন ভেরিয়েবল

একটা শর্ত সত্য হওয়ার জন্য অপেক্ষা করার primitive — সবসময় একটা mutex-এর সাথে জোড়ায় ব্যবহৃত। Wait অবশ্যই `while` loop-এ রাখতে হয়, `if`-এ নয়।

also: condvar, monitor

pthread_mutex_lock(&m);
while (!condition)                    /* while — if নয় */
    pthread_cond_wait(&cv, &m);       /* atomically: unlock, sleep, relock */
/* এখানে condition সত্য আর mutex ধরা আছে */
pthread_mutex_unlock(&m);

pthread_cond_wait তিনটা কাজ atomically করে: mutex ছাড়ে, ঘুমায়, জেগে উঠে আবার mutex নেয়। এই atomicity ছাড়া “unlock করলাম, তারপর ঘুমাতে গেলাম” — এর মাঝে signal এলে সেটা হারিয়ে যেত (lost wakeup)।

কেন while, if নয় — দুইটা কারণ:

  1. Spurious wakeup — POSIX অনুমতি দেয় যে cond_wait কোনো signal ছাড়াই ফিরতে পারে
  2. আরো গুরুত্বপূর্ণ — reacquire race: signal পাওয়ার পর mutex আবার নেওয়ার আগে অন্য একটা thread ঢুকে শর্তটা আবার মিথ্যা করে দিতে পারে

দ্বিতীয় কারণটাই বাস্তবে বেশি ঘটে, আর এটা spurious wakeup না থাকলেও while বাধ্যতামূলক করে দেয়।

signal বনাম broadcast:

  • pthread_cond_signal — একজনকে জাগায়। যথেষ্ট যদি সব waiter একই শর্তের জন্য অপেক্ষা করে
  • pthread_cond_broadcast — সবাইকে। লাগে যখন waiter-রা ভিন্ন শর্তের জন্য অপেক্ষা করছে, বা একাধিক জনের এগোনো সম্ভব

সন্দেহ হলে broadcast নিরাপদ (শুধু কিছু অপ্রয়োজনীয় wakeup), signal ভুল জায়গায় ব্যবহার করলে thread চিরকাল ঘুমিয়ে থাকতে পারে।