שני הסנטים שלי על מוטקס וסמפור ב C #

סנכרון חוטים משמש כדי למנוע מרוב נושאים לגשת למשאב משותף במקביל. Mutex וסמפור הם שני המושגים החשובים ביותר. בואו להבין מה שניהם ומתי עלינו להשתמש בהם.

לפני שנתחיל בדיון, בואו נסתכל במהירות על מושגי היסוד. חוט הוא יחידת הביצוע הקטנה ביותר בתהליך. בעיקרו של דבר, ריבוי השחלות מסייע לך לבצע מספר משימות בו זמנית ומכאן להגדיל את התפוקה הכוללת של היישום.

Mutex הוא פרימיטיבי סנכרון שיכול לעבוד על פני תהליכים - כלומר, הוא יכול לשמש לסינכרון בין תהליכים. סמפורה להפך היא כזו המאפשרת לך להגביל את מספר השרשורים שיש להם גישה למשאב משותף באותה נקודת זמן. בעיקרו של דבר, סמפור הוא צורה כללית יותר של מוטקס.

סמפור משמשת להגבלת מספר הנושאים שיכולים להיות בעלי גישה למשאב משותף במקביל. למעשה, הוא משמש להגבלת מספר הצרכנים עבור משאב משותף מסוים במקביל. אתה יכול לנצל את Semaphore כדי ליישם נעילה לא בלעדית ומכאן להגביל את המקבילות.

שים לב ש- Mutex משמש לנעילה בלעדית במשאב משותף. במילים אחרות, Mutex מאפשר לך לרכוש נעילה בלעדית - לכל שרשור אחד תהיה גישה למשאב משותף בנקודת זמן נתונה. נעילה בלעדית משמשת כדי להבטיח שבכל נקודת זמן נתונה חוט אחד ויחיד יכול להיכנס למקטע קריטי. ניתן להגדיר קטע קריטי כמבנה נתונים או משאב המשותף למספר שרשורים, אך שרשור אחד ויחיד יכול לקבל גישה אליו בכל נקודת זמן נתונה.

המחלקה System.Threading.Mutex מייצגת Mutex והמחלקה System.Threading.Semaphore משמשת לעבודה עם Semaphores. אתה יכול להשתמש בשיטת WaitOne במופע של מחלקת Mutex כדי לנעול ולהשתמש בשיטת ReleaseMutex כדי לבטל את הנעילה.

Mutex mutexObject = new Mutex(false, "Demo");

if (!mutexObject.WaitOne(TimeSpan.FromSeconds(10), false))

     {

             Console.WriteLine("Quitting for now as another instance is in execution...");

               return;

     }

כדי ליצור סמפור ב- C #, עליך ליצור מופע של מחלקת הסמפור. בעת יצירת מופע של סמפור, עליך להעביר שני ארגומנטים לבנאי הטיעונים שלו. בעוד שהארגומנט הראשון משמש לציון מספר ערכי המשאבים הראשוניים, הארגומנט השני משמש לציון המספר המרבי של ערכי משאבים בו זמנית. שים לב שאם תרצה לשריין את כל החריצים לשרשורים החדשים שייווצרו, עליך לציין ערכים זהים לשני הפרמטרים הללו. קטע הקוד הבא ממחיש כיצד ניתן ליצור סמפור ב- C #.

public static Semaphore threadPool = new Semaphore(3, 5);

עיין בקטע הקוד המופיע לעיל. ההצהרה לעיל יוצרת אובייקט סמפורי בשם threadPool שיכול לתמוך במקסימום 5 בקשות בו זמנית. שים לב שהספירה הראשונית מוגדרת ל- 3 כפי שצוין בפרמטר הראשון לבנאי. זה מרמז על כך ששני חריצים שמורים לשרשור הנוכחי ו -3 חריצים זמינים לשרשורים אחרים. בואו נכתוב קצת קוד!

קטע הקוד הבא מראה כיצד ניתן ליצור ולהתחיל 10 שרשורים באמצעות מחלקת שרשור הזמינה במרחב השמות מערכת. שים לב כיצד נעשה שימוש בציר ThreadStart.

for (int i = 0; i < 10; i++)

{

   Thread threadObject = new Thread(new ThreadStart(PerformSomeWork));

   threadObject.Name = "Thread Name: " + i;

   threadObject.Start();

}

הנה הקוד של שיטת PerformSomeWork. זו השיטה שמכילה למעשה את הקוד לעבודה עם סמפורות.

private static void PerformSomeWork()

       {

           threadPool.WaitOne();

           Console.WriteLine("Thread {0} is inside the critical section...", Thread.CurrentThread.Name);

           Thread.Sleep(10000);

           threadPool.Release();

       }

עיין בשיטת PerformSomeWork המפורטת לעיל. שיטת WaitOne נקראת במופע Semaphore לחסום את החוט הנוכחי עד לקבלת אות. שיטת השחרור נקראת באותו מופע לשחרור הסמפור. הנה רשימת הקוד המלאה לעיונך.

class SemaphoreDemo

   {

       public static Semaphore threadPool = new Semaphore(3, 5);

       public static void Main(string[] args)

       {

           for (int i = 0; i < 10; i++)

           {

               Thread threadObject = new Thread(new ThreadStart(PerformSomeWork));

               threadObject.Name = "Thread Name: " + i;

               threadObject.Start();

           }

           Console.ReadLine();

       }

       private static void PerformSomeWork()

       {

           threadPool.WaitOne();

           Console.WriteLine("Thread {0} is inside the critical section...", Thread.CurrentThread.Name);

           Thread.Sleep(10000);

           threadPool.Release();

       }

   }