באמצעות מחלקת Mutex, ננעל מקטע קריטי עבור תהליך בודד (לא מדובר ב-Thread, אלא תהליך), זוהי למעשה הנעילה האקסקלוסיבית האחרונה שנעבור עליה במסגרת מדריך זה
כפי שהוסבר בפרק ד' של המדריך, קיימים מספר סוגים של נעילות אקסקלוסיביות.
בפרקים זה נלמד על מחלקת Mutex, שבאמצעותה נוכל לנעול מקטע קריטי לתהליך בודד.
מחלקת Mutex
באמצעות מחלקת Mutex, ננעל מקטע קריטי עבור תהליך בודד (לא מדובר ב-Thread, אלא תהליך).
בדומה ל-Lock ו-Monitor, גם Mutex יאפשר גישה לאובייקט ל-Thread אחד כל פעם בזמן נתון.
מחלקה זו שייכת גם היא ל- System.Threading:
כפי שניתן לראות, למחלקה זו יש מספר בנאים.
כעת נבאר את אופן הפעולה של כל אחת מן המתודות והבנאים של המחלקה.
בנאי המחלקה
()Mutex – מאתחל מופע של מחלקת Mutex עם מאפיינים דיפולטיביים.
Mutex(bool initiallyOwned) – גם מאתחל מופע של מחלקת Mutex, רק שנשלח לו Bool כפרמטר שיקבע אם ל-Thread שהפעיל את הבנאי יש בלעדיות על המקטע הקריטי.
TryEnter
Mutex(bool initiallyOwned, string name) – מאתחל מופע של Mutex, נשלח לו Bool כפרמטר שיקבע אם ל-Thread שהפעיל את הבנאי יש בלעדיות על המקטע הקריטי, ומחרוזת (String) שתסמל את שם ה-Mutex.
Mutex(bool initiallyOwned, string name, out bool createdNew) – מאתחל מופע של Mutex, נשלח לו Bool כפרמטר שיקבע אם ל-Thread שהפעיל את הבנאי יש בלעדיות על המקטע הקריטי, מחרוזת (String) שתסמל את שם ה-Mutex, ו-Bool נוסף אשר נשלח כ-Out פרמטר, על מנת שנוכל לדעת מה הערך של ה-Bool הראשון ששלחנו.
המתודות של מחלקת Mutex
OpenExisting(string name) – במתודה זו נוכל להשתמש על מנת לפתוח אובייקט Mutex מסוים, נציין את שמו של האובייקט בפרמטר.
אם לא סופק שם תיזרק חריגת ArgumentException .
אם השם ארוך מ-256 אותיות – תיזרק חריגת ArgumentNullException.
TryOpenExisting(string name, [NotNullWhen(true)] out Mutex? result) – במתודה זו נוכל להשתמש על מנת לנסות לפתוח אובייקט Mutex מסוים, נציין את שמו של האובייקט בפרמטר,
ה-Out Parameter שנקרא result, יחזיר לנו את אובייקט בעל אותו השם במידה והפתיחה הצליחה.
()ReleaseMutex – משחרר את האובייקט מהנעילה.
שימו לב ל-Code Snippet הבא שבו נדגים כיצד אנו בודקים אם יותר מתהליך אחד רץ ברקע.
כלומר שבמידה ואכן מדובר בתהליך בודד התוכנית תמשיך לפעול, אחרת תסתיים:
using System.Threading; namespace ThreadingDemo { class Program { static Mutex? mutex; static void Main() { if (!IsSingleInstance()) { Console.WriteLine("There's more than one instance"); } else { Console.WriteLine("There's One instance"); } } static bool IsSingleInstance() { try { Mutex.OpenExisting("MyMutex"); } catch { mutex = new Mutex(true, "MyMutex"); return true; } return false; } } }
כפי שניתן לראות, הרצנו פעמיים את התוכנית במקביל.
בפעם הראשונה התוכנית רצה ללא שום קושי – וזאת משום שבאותו הזמן היה מדובר בתהליך בודד.
אך כאשר הפעלנו את התוכנית שוב במקביל – התהליך החדש נעצר, וזאת משום שיש כבר תהליך אחד פועל.
כלומר שהגבלנו את התוכנית כך שהיא תוכל להיות מנוהלת על ידי תהליך אחד בודד בזמן נתון.
במידה והיינו מעוניינים לאפשר ליותר מתהליך אחד להיכנס לקוד אך עדיין להגביל את הקוד לתהליכים מסוימים –
היינו יכולים להשתמש בנעילה שאינה אקסקלוסיבית.
בפרק הבא של המדריך נלמד על נעילות שאינן אקסקלוסיביות, נתחיל מ- Semaphore.
לקריאה מורחבת על Thread ו-Threading באתר של מייקרוסופט יש ללחוץ כאן.