פונקציות הקשורות לסמפורים

  • wait(sem)

המתנה על סמפור.

  • signal(sem)

שחרור תהליך ממתין על סמפור.

  • screate(count)

מקצה סמפור חדש ומחזירה את האינדקס שלו.

  • sdelete(sem)

מחיקת סמפור והכנסת כל התהליכים הממתינים לו לרשימת ה-ready.

  • scount(sem)

מחזירה את ערכו הנוכחי של הסמפור sem.

  • signaln(s, count)

שקולה לביצוע count פעמים של signal(s) אך יעילה יותר. ניתן להשתמש בפונקציה זו למימוש גרף תלויות.

  • sreset(s, count)

משנה את ערך הסמפור לערך חיובי כלשהו, מעבירה את כל הממתינים עליו לתור ה-ready.

  • wait()

פעולת wait:

  1. בודקת שהסמפור חוקי.
  2. מורידה את מונה הסמפור ב-1.
  3. אם המונה שלילי:

o        משנה את מצב התהליך הנוכחי ל-PRWAIT.
o        מכניסה לרשומת התהליך את מזהה הסמפור.
o        מכניסה את התהליך לתור הממתינים של הסמפור.
o        קוראת ל-resched כדי להוציא את התהליך הנוכחי מהמעבד.

לא ניתן להפעיל את הפונקציה על סמפור שלא אותחל או שכבר שוחרר. הקריאה ל-resched במהלך הפונקציה הכרחית, כי אחרי שהכנסנו את התהליך הנוכחי לתור המתנה, אין תהליך נוכחי במערכת.

  • signal()

פעולת signal:

  1. בודקת שהסמפור חוקי.
  2. מוסיפה 1 למונה הסמפור.
  3. אם לפני ההוספה היה הסמפור שלילי, מוציאה את הראשון בתור הסמפור, מכניסה אותו לתור ה-ready וקוראת ל-resched.

לא ניתן להפעיל את הפונקציה על סמפור שלא אותחל או שכבר שוחרר.

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

הפונקציות wait, signal מקיימות ומניחות את קיום השמורה הבאה:

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

כדי לקיים את השמורה:

בגלל ש-wait מקטינה את המונה, היא מוסיפה את התהליך הנוכחי לתור אם המונה שלילי.

בגלל ש-signal מגדילה את המונה, היא מוציאה איבר מהתור במידה והתור איננו ריק.

  • screate()

פעולת screate:

  1. מקבלת כארגומנט את הערך ההתחלתי של המונה.
  2. בודקת שהמונה איננו שלילי (כדי להימנע מהפרת השמורה)
  3. קוראת לפונקציה newsem() כדי לקבל מזהה של סמפור פנוי, ולתפוס אותו.
  4. אם נמצא סמפור פנוי, מעדכנים את המונה שלו.
  5. אין צורך באתחול תור הסמפור, וזאת מכיוון שעל מנת לחסוך זמן בשעת יצירת הסמפורים, המערכת מקצה את ראשי וזנבות התורים עבור כל הסמפורים האפשריים כבר בזמן האתחול.
  • newsem()

פונקציה פנימית בעזרתה screate() מוצאת מציין סמפור פנוי. הפונקציה סורקת את טבלת הסמפורים ומוצאת תא פנוי, או מחזירה SYSERR אם אין כזה. כמו כן הפונקציה מסמנת את התא שנמצא כתפוס.

הפונקציה מסתמכת על כך שבעת אתחול המערכת הוצב הקבוע SFREE לכל רשומות הסמפורים.

הפונקציה מוגדרת כ-LOCAL, כלומר פונקציה פנימית של מנגנון הסמפורים, שלשאר חלקי מערכת ההפעלה אין גישה אליו.

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

  • sdelete()

פעולת sdelete:

  1. בודקת שהסמפור חוקי ואינו כבר משוחרר.
  2. מסמנת בטבלת הסמפורים שהסמפור משוחרר.
  3. עוברת על תור הממתינים לסמפור ומעבירה אותם אל תור ה-ready.
  4. קוראת ל-resched.

בסוף לולאת ה-while המשחררת את כל התהליכים מבצעים resched, וכך יתכן שאחד מהתהליכים אלו יהפוך לפעיל. נשים לב כי מחיקת סמפור כאשר יש תהליכים המחכים לו היא פעולה מסוכנת. ישנן מערכות הפעלה בהם לא ניתן לשחרר סמפור אשר מחכים עליו תהליכים.

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

  • scount()

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

  • signaln()

פעולת signaln:

  1. פעולתה זהה לקריאה ל-signal n פעמים.
  2. הקריאה ל-signaln יעילה יותר מכיוון שהיא מבצעת resched רק פעם אחת.
  3. הפעולה חיונית למימוש גרף תלויות, וזאת מכיוון שאם היינו משתמשים ב-signal, יתכן שאחד התהליכים שאנו מעירים הוא בעדיפות גדולה מזו של התהליך שקרא ל-signaln, ואז פעולת signaln תיקטע ובמקומה יתחיל לרוץ התהליך שהוער.


תגיות המסמך:

מאת: באסל

תודה

הסברתם את זה, כמו שאר הנושאים, באופן הכי ברור שיש.
שיתוף:
| עוד