CodeGym /جاوا بلاگ /Random-UR /ایک Mutex، ایک مانیٹر، اور ایک Semaphore کے درمیان فرق
John Squirrels
سطح
San Francisco

ایک Mutex، ایک مانیٹر، اور ایک Semaphore کے درمیان فرق

گروپ میں شائع ہوا۔
ہائے! جب آپ نے CodeGym پر ملٹی تھریڈنگ کا مطالعہ کیا، تو آپ کو اکثر "میوٹیکس" اور "مانیٹر" کے تصورات کا سامنا کرنا پڑا۔ جھانکنے کے بغیر، کیا آپ کہہ سکتے ہیں کہ وہ کیسے مختلف ہیں؟ :) اگر ہاں، تو شاباش! اگر نہیں (یہ سب سے عام ہے)، تو یہ کوئی تعجب کی بات نہیں ہے۔ "Mutex" اور "مانیٹر" دراصل متعلقہ تصورات ہیں۔ مزید برآں، جب آپ اسباق پڑھتے ہیں اور دوسری ویب سائٹس پر ملٹی تھریڈنگ کے بارے میں ویڈیوز دیکھتے ہیں، تو آپ کو ایک اور اسی طرح کا تصور نظر آئے گا: "سیمافور"۔ اس میں مانیٹر اور میوٹیکس سے بھی بہت ملتا جلتا فنکشن ہے۔ اس لیے ہم ان تین شرائط کی چھان بین کرنے جا رہے ہیں۔ ہم چند مثالوں کو دیکھیں گے اور اس بات کی قطعی سمجھ حاصل کریں گے کہ یہ تصورات ایک دوسرے سے کیسے مختلف ہیں :)

Mutex

ایک mutex (یا تالا) دھاگوں کی مطابقت پذیری کے لیے ایک خاص طریقہ کار ہے۔ ایک جاوا میں ہر چیز کے ساتھ "منسلک" ہوتا ہے — آپ پہلے ہی جانتے ہیں کہ :) اس سے کوئی فرق نہیں پڑتا کہ آپ معیاری کلاسز استعمال کرتے ہیں یا اپنی کلاسیں بناتے ہیں، جیسے Cat اور Dog : تمام کلاسز کی تمام اشیاء کا ایک mutex ہوتا ہے ۔ "mutex" کی اصطلاح "MUTual exclusion" سے نکلی ہے، جو اس کے مقصد کو پوری طرح بیان کرتی ہے۔ جیسا کہ ہم نے اپنے پچھلے اسباق میں سے ایک میں کہا تھا، ایک mutex اس بات کو یقینی بناتا ہے کہ ایک وقت میں صرف ایک دھاگے کی آبجیکٹ تک رسائی ہو۔ میوٹیکس کی ایک مقبول حقیقی زندگی کی مثال میں بیت الخلاء شامل ہیں۔ جب کوئی شخص ٹوائلٹ پارٹیشن میں داخل ہوتا ہے تو وہ دروازے کو اندر سے بند کر دیتا ہے۔ بیت الخلا ایک ایسی چیز کی طرح ہے جس تک متعدد دھاگوں سے رسائی حاصل کی جاسکتی ہے۔ تقسیم کے دروازے پر تالا ایک mutex کی طرح ہے، اور باہر لوگوں کی لائن دھاگوں کی نمائندگی کرتی ہے۔ دروازے پر لگا تالا ٹوائلٹ کا میوٹیکس ہے: یہ یقینی بناتا ہے کہ صرف ایک شخص اندر جا سکتا ہے۔ ایک mutex، ایک مانیٹر، اور سیمفور میں کیا فرق ہے؟  - 2دوسرے الفاظ میں، ایک وقت میں صرف ایک تھریڈ مشترکہ وسائل کے ساتھ کام کر سکتا ہے۔ دوسرے دھاگوں (لوگوں) کی طرف سے مقبوضہ وسائل تک رسائی حاصل کرنے کی کوششیں ناکام ہو جائیں گی۔ ایک mutex میں کئی اہم خصوصیات ہیں. سب سے پہلے ، صرف دو حالتیں ممکن ہیں: "غیر مقفل" اور "لاک"۔ اس سے ہمیں یہ سمجھنے میں مدد ملتی ہے کہ یہ کیسے کام کرتا ہے: آپ بولین متغیرات (سچ/غلط) یا بائنری نمبرز (0/1) کے ساتھ متوازی کھینچ سکتے ہیں۔ دوسرا ، ریاست کو براہ راست کنٹرول نہیں کیا جا سکتا۔ جاوا کے پاس کوئی طریقہ کار نہیں ہے جو آپ کو واضح طور پر کوئی چیز لینے، اس کا mutex حاصل کرنے اور مطلوبہ حیثیت تفویض کرنے دیتا ہے۔ دوسرے الفاظ میں، آپ کچھ ایسا نہیں کر سکتے ہیں:
Object myObject = new Object();
Mutex mutex = myObject.getMutex();
mutex.free();
اس کا مطلب یہ ہے کہ آپ کسی شے کے mutex کو جاری نہیں کرسکتے ہیں۔ صرف جاوا مشین کو اس تک براہ راست رسائی حاصل ہے۔ پروگرامر زبان کے ٹولز کے ذریعے mutexes کے ساتھ کام کرتے ہیں۔

مانیٹر

ایک مانیٹر ایک mutex پر ایک اضافی "سپر سٹرکچر" ہے۔ در حقیقت ، مانیٹر کوڈ کا ایک حصہ ہے جو پروگرامر کے لئے "پوشیدہ" ہے۔ جب ہم نے پہلے mutexes کے بارے میں بات کی تھی، تو ہم نے ایک سادہ سی مثال دی:
public class Main {

   private Object obj = new Object();

   public void doSomething() {

       // ...some logic, available for all threads

       synchronized (obj) {

           // Logic available to just one thread at a time
       }
   }
}
مطابقت پذیر مطلوبہ الفاظ کے ساتھ نشان زد کوڈ بلاک میں ، ہمارے obj آبجیکٹ کا mutex حاصل کیا جاتا ہے۔ بہت اچھا، ہم تالا حاصل کر سکتے ہیں، لیکن "تحفظ" کس طرح فراہم کی جاتی ہے؟ جب ہم لفظ کو مطابقت پذیر دیکھتے ہیں ، تو کیا چیز دوسرے تھریڈز کو بلاک میں داخل ہونے سے روکتی ہے؟ تحفظ مانیٹر سے آتا ہے! کمپائلر مطابقت پذیر مطلوبہ الفاظ کو کوڈ کے کئی خاص ٹکڑوں میں تبدیل کرتا ہے۔ ایک بار پھر، doSomething() طریقہ کے ساتھ اپنی مثال پر واپس آتے ہیں ۔ ہم اس میں شامل کریں گے:
public class Main {

   private Object obj = new Object();

   public void doSomething() {

       // ...some logic, available for all threads

       // Logic available to just one thread at a time
       synchronized (obj) {

           /* Do important work that requires that the object
           be accessed by only one thread */
           obj.someImportantMethod();
       }
   }
}
کمپائلر کے اس کوڈ کو تبدیل کرنے کے بعد "ہڈ کے نیچے" کیا ہوتا ہے:
public class Main {

   private Object obj = new Object();

   public void doSomething() throws InterruptedException {

       // ...some logic, available for all threads

       // Logic available to just one thread at a time:

       /* as long as the object's mutex is busy,
       all the other threads (except the one that acquired it) are put to sleep */
       while (obj.getMutex().isBusy()) {
           Thread.sleep(1);
       }

       // Mark the object's mutex as busy
       obj.getMutex().isBusy() = true;

       /* Do important work that requires that the object
       be accessed by only one thread */
       obj.someImportantMethod();

       // Free the object's mutex
       obj.getMutex().isBusy() = false;
   }
}
یقینا، یہ ایک حقیقی مثال نہیں ہے. یہاں، ہم نے جاوا مشین کے اندر کیا ہوتا ہے اس کی عکاسی کرنے کے لیے جاوا جیسا کوڈ استعمال کیا۔ اس نے کہا، یہ چھدم کوڈ اس بات کی ایک بہترین تفہیم دیتا ہے کہ اصل میں مطابقت پذیر بلاک کے اندر آبجیکٹ اور تھریڈز کے ساتھ کیا ہوتا ہے اور کس طرح مرتب کرنے والا اس کلیدی لفظ کو کئی بیانات میں تبدیل کرتا ہے جو پروگرامر کے لیے "پوشیدہ" ہیں۔ بنیادی طور پر، جاوا مانیٹر کی نمائندگی کرنے کے لیے مطابقت پذیر کلیدی لفظ استعمال کرتا ہے ۔ وہ تمام کوڈ جو آخری مثال میں مطابقت پذیر کلیدی لفظ کے بجائے ظاہر ہوتا ہے مانیٹر ہے۔

سیمفور

ایک اور لفظ جس کا آپ کو ملٹی تھریڈنگ کے اپنے ذاتی مطالعہ میں سامنا ہوگا وہ ہے "سیمافور"۔ آئیے معلوم کریں کہ یہ کیا ہے اور یہ مانیٹر اور میوٹیکس سے کیسے مختلف ہے۔ سیمفور کچھ وسائل تک رسائی کو ہم آہنگ کرنے کا ایک ٹول ہے۔ اس کی مخصوص خصوصیت یہ ہے کہ یہ سنکرونائزیشن میکانزم بنانے کے لیے کاؤنٹر کا استعمال کرتا ہے۔ کاؤنٹر ہمیں بتاتا ہے کہ کتنے دھاگے بیک وقت مشترکہ وسائل تک رسائی حاصل کر سکتے ہیں۔ ایک mutex، ایک مانیٹر، اور سیمفور میں کیا فرق ہے؟  - 3جاوا میں سیمفورس کی نمائندگی سیمفور کلاس کرتی ہے۔ سیمفور آبجیکٹ بناتے وقت، ہم درج ذیل کنسٹرکٹرز استعمال کر سکتے ہیں۔
Semaphore(int permits)
Semaphore(int permits, boolean fair)
ہم مندرجہ ذیل کنسٹرکٹر کو دیتے ہیں:
    int permits - کاؤنٹر کی ابتدائی اور زیادہ سے زیادہ قیمت۔ دوسرے الفاظ میں، یہ پیرامیٹر اس بات کا تعین کرتا ہے کہ مشترکہ وسائل تک بیک وقت کتنے دھاگوں تک رسائی ہو سکتی ہے۔
  • boolean fair — ترتیب قائم کرتا ہے جس میں تھریڈز تک رسائی حاصل ہو گی۔ اگر منصفانہ درست ہے، تو ویٹنگ تھریڈز تک رسائی اسی ترتیب سے دی جاتی ہے جس میں انہوں نے درخواست کی تھی۔ اگر یہ غلط ہے، تو ترتیب کا تعین تھریڈ شیڈیولر کے ذریعے کیا جاتا ہے۔
سیمفور کے استعمال کی ایک بہترین مثال ڈائننگ فلسفی کا مسئلہ ہے۔ ایک mutex، ایک مانیٹر، اور سیمفور میں کیا فرق ہے؟  - 4سمجھنے کی سہولت کے لیے، ہم اسے تھوڑا سا آسان کریں گے۔ تصور کریں کہ ہمارے پاس 5 فلسفی ہیں جنہیں دوپہر کا کھانا کھانے کی ضرورت ہے۔ مزید برآں، ہمارے پاس ایک میز ہے جس میں بیک وقت دو سے زیادہ لوگ نہیں رہ سکتے۔ ہمارا کام تمام فلسفیوں کو کھانا کھلانا ہے۔ ان میں سے کسی کو بھی بھوکا نہیں رہنا چاہئے، اور ان میں سے کسی کو بھی میز پر بیٹھنے کی کوشش کرتے وقت ایک دوسرے کو "بلاک" نہیں کرنا چاہئے (ہمیں تعطل سے بچنا چاہئے)۔ یہاں ہے کہ ہمارے فلسفی طبقے کی طرح نظر آئے گا:
class Philosopher extends Thread {

   private Semaphore sem;

   // Did the philosopher eat?
   private boolean full = false;

   private String name;

   Philosopher(Semaphore sem, String name) {
       this.sem=sem;
       this.name=name;
   }

   public void run()
   {
       try
       {
           // If the philosopher has not eaten
           if (!full) {
               // Ask the semaphore for permission to run
               sem.acquire();
               System.out.println(name + " takes a seat at the table");

               // The philosopher eats
               sleep(300);
               full = true;

               System.out.println(name + " has eaten! He leaves the table");
               sem.release();

               // The philosopher leaves, making room for others
               sleep(300);
           }
       }
       catch(InterruptedException e) {
           System.out.println("Something went wrong!");
       }
   }
}
اور ہمارے پروگرام کو چلانے کا کوڈ یہ ہے:
public class Main {

   public static void main(String[] args) {

       Semaphore sem = new Semaphore(2);
       new Philosopher(sem, "Socrates").start();
       new Philosopher(sem,"Plato").start();
       new Philosopher(sem,"Aristotle").start();
       new Philosopher(sem, "Thales").start();
       new Philosopher(sem, "Pythagoras").start();
   }
}
ہم نے ایک سیمفور بنایا جس کا کاؤنٹر شرط کو پورا کرنے کے لیے 2 پر سیٹ کیا گیا ہے: صرف دو فلسفی بیک وقت کھا سکتے ہیں۔ یعنی بیک وقت صرف دو تھریڈ چل سکتے ہیں، کیونکہ ہمارے فلاسفر طبقے کو تھریڈ وراثت میں ملتا ہے ! سیمفور کلاس کے حاصل () اور ریلیز () طریقے اس کے رسائی کاؤنٹر کو کنٹرول کرتے ہیں۔ acquire() طریقہ سیمفور سے وسائل تک رسائی مانگتا ہے۔ اگر کاؤنٹر >0 ہے تو رسائی دی جاتی ہے اور کاؤنٹر کو 1 تک کم کیا جاتا ہے۔ ریلیز() طریقہ پہلے سے دی گئی رسائی کو "ریلیز" کرتا ہے، اسے کاؤنٹر پر واپس کر دیتا ہے (سیمفور کے رسائی کاؤنٹر کو 1 تک بڑھاتا ہے)۔ جب ہم پروگرام چلاتے ہیں تو ہمیں کیا ملتا ہے؟ کیا مسئلہ حل ہوگیا؟ کیا ہمارے فلسفی اپنی باری کے انتظار میں نہیں لڑیں گے؟ :) ہمیں جو کنسول آؤٹ پٹ ملا ہے وہ یہ ہے:

Socrates takes a seat at the table 
Plato takes a seat at the table 
Socrates has eaten! He leaves the table
Plato has eaten! He leaves the table 
Aristotle takes a seat at the table 
Pythagoras takes a seat at the table 
Aristotle has eaten! He leaves the table
Pythagoras has eaten! He leaves the table 
Thales takes a seat at the table 
Thales has eaten! He leaves the table
ہم نے کر لیا! اور اگرچہ تھیلس کو اکیلے کھانا کھانا پڑا، مجھے نہیں لگتا کہ ہم نے اسے ناراض کیا ہے :) آپ نے میوٹیکس اور سیمفور کے درمیان کچھ مماثلتیں دیکھی ہوں گی۔ درحقیقت، ان کا ایک ہی مشن ہے: کچھ وسائل تک رسائی کو ہم آہنگ کرنا۔ ایک mutex، ایک مانیٹر، اور سیمفور میں کیا فرق ہے؟  - 5فرق صرف اتنا ہے کہ کسی شے کا میوٹیکس ایک وقت میں صرف ایک تھریڈ سے حاصل کیا جا سکتا ہے، جبکہ سیمفور کی صورت میں، جو تھریڈ کاؤنٹر کا استعمال کرتا ہے، کئی تھریڈز بیک وقت وسائل تک رسائی حاصل کر سکتے ہیں۔ یہ محض اتفاق نہیں ہے :) ایک mutex دراصل ایک سیمفور ہے جس کی گنتی 1 ہے۔ دوسرے لفظوں میں، یہ ایک سیمفور ہے جو ایک ہی دھاگے کو ایڈجسٹ کر سکتا ہے۔ اسے "بائنری سیمفور" کے نام سے بھی جانا جاتا ہے کیونکہ اس کے کاؤنٹر کی صرف 2 اقدار ہو سکتی ہیں — 1 ("غیر مقفل") اور 0 ("لاک")۔ یہی ہے! جیسا کہ آپ دیکھ سکتے ہیں، آخر یہ اتنا الجھا ہوا نہیں ہے :) اب، اگر آپ انٹرنیٹ پر ملٹی تھریڈنگ کا مزید تفصیل سے مطالعہ کرنا چاہتے ہیں، تو آپ کے لیے ان تصورات کو نیویگیٹ کرنا قدرے آسان ہوگا۔ اگلے اسباق میں ملتے ہیں!
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION