1 / 42

מערכות הפעלה

מערכות הפעלה. תרגול 6 – מימוש סינכרון תהליכים. מה בתכנית?. מימוש סנכרון תהליכים ב- XINU Mutexes. אמצעי תקשורת וסינכרון. סמפור wait(s)/signal(s) שליחת הודעות send(pid, msg)/receive() mutex (מניעה הדדית). מימוש סמפורים. מצב התהליך – PRWAIT

derora
Download Presentation

מערכות הפעלה

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. מערכות הפעלה תרגול 6 – מימוש סינכרון תהליכים

  2. מה בתכנית? • מימוש סנכרון תהליכים ב-XINU • Mutexes מערכות הפעלה - תרגול 2

  3. אמצעי תקשורת וסינכרון • סמפור • wait(s)/signal(s) • שליחת הודעות • send(pid, msg)/receive() • mutex (מניעה הדדית) מערכות הפעלה - תרגול 2

  4. מימוש סמפורים • מצב התהליך – PRWAIT התהליך המחכה נמצא במצב PRWAIT המיוחד לסמפורים • תור לכל סמפור לכל סמפור נשמר תור FIFO של התהליכים המחכים לו, כך שsignal- יוכל לשחרר את הראשון שבהם, ולהעבירו לתור ה-ready • טבלת סמפורים semaph עם כניסות מסוג sentry • כל כניסה מכילה מונה, מצביעים לתור (בטבלת q) ודגל הכניסה (SFREE/SUSED) • ערך מזהה הסמפור sid הוא האינדקס של כניסתו בטבלת הסמפורים מערכות הפעלה - תרגול 2

  5. מימוש סמפורים – sem.h מערכות הפעלה - תרגול 2

  6. קריאת מ"ה wait – wait.c מערכות הפעלה - תרגול 2

  7. קריאת מ"ה wait • ביצוע wait לא מופרע באמצע ע"י מערכת ההפעלה. הגנה באמצעות disable/restore. אולם החלפת הקשר היא אפשרית גם באמצע עקב reschedיזום • לא ניתן לבצע wait על סמפור שלא נוצר, או שכבר שוחרר • הכנסה לסוף תור הסמפור (כלומר FIFO) • הקריאה לresched- הכרחית מערכות הפעלה - תרגול 2

  8. קריאת מ"ה signal – signal.c מערכות הפעלה - תרגול 2

  9. קריאת מ"ה signal • ביצוע signalלא מופרע באמצע ע"י מערכת ההפעלה. הגנה באמצעות disable/restore. אולם החלפת הקשר היא אפשרית גם באמצע עקב reschedיזום • לא ניתן לבצע signal על סמפור שלא נוצר, או שכבר שוחרר • ההוצאה מראש תור הסמפורים (FIFO) • האם הקריאה ל-resched הכרחית כפי שהיתה הכרחית ב-wait? מערכות הפעלה - תרגול 2

  10. קריאת מ"ה screate – screate.c לא ניתן ליצור סמפור עם ערך התחלתי שלילי. מה המשמעות של ערך שלילי? מערכות הפעלה - תרגול 2

  11. קריאת מ"ה screate • ביצוע signalלא מופרע באמצע ע"י מערכת ההפעלה. הגנה באמצעות disable/restore. אולם החלפת הקשר היא אפשרית גם באמצע עקב reschedיזום • לא ניתן לבצע signal על סמפור שלא נוצר, או שכבר שוחרר • ההוצאה מראש תור הסמפורים (FIFO) • האם הקריאה ל-resched הכרחית כפי שהיתה הכרחית ב-wait? מערכות הפעלה - תרגול 2

  12. קריאת מ"ה screate – המשך בעת אתחול המערכת הוצב קבוע SFREE לכל רשומות הסמפורים מערכות הפעלה - תרגול 2

  13. קריאת מ"ה sdelete מערכות הפעלה - תרגול 2

  14. קריאת מ"ה sdelete • אם, בעת מחיקת הסמפור, קיימים תהליכים המחכים לו, משחררים את כל התהליכים • בסוף לולאתwhile מבצעים resched. האם מותר גם בתוך הלולאה? • לשים לב:מחיקת סמפור כאשר יש תהליכים המחקים בתור היא פעולה מסוכנת ולא טבעית (הרי יש סיבה שבגללה הם מחכים לסמפור...) • ישנן מערכות הפעלה בהן לא ניתן לשחרר סמפור שתורו לא ריק מערכות הפעלה - תרגול 2

  15. signaln.c ready() מרכזת את כל הטיפול בתור התהליכים המוכנים מערכות הפעלה - תרגול 2

  16. sreset.c מה ההבדל בין קריאה ל-sreset לבין שתי קריאות רצופות ל-sdelete ו-screate? מערכות הפעלה - תרגול 2

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

  18. הודעות ב-XINU XINU מוגבלת מאוד באמצעי העברת ההודעות שלה. סוגי העברה: • משלוח לא חוסם (send למיניהם) • קבלה חוסמת ולא חוסמת (receiveclr, receive) • שליחת ההודעות לתהליך מסויים מערכות הפעלה - תרגול 2

  19. הודעות ב-XINU • באמצעות העברת ההודעות ב-XINU ניתן: • להעביר מסרים • לתאם בין תהליכים (בנוסף לסמפורים) • הגבלות: • הודעה באורך של שני בתים בלבד (integer) • כשמגיעים מספר מסרים, רק הראשון מתקבל והשאר אובדים מערכות הפעלה - תרגול 2

  20. העברת הודעות – מבנה נתונים • מצב התהליך – PRRECV, תהליך מחכה נמצא במצב PRRECV (מיוחד להמתנה להודעות) • שדות pmsgו-phasmsg בטבלת התהליכים • ההודעה הנשלחת לתהליך מוכנסת לשדה pmsg ברשומת התהליך • השדה phasmsg מסמן אם יש הודעה ממתינה מערכות הפעלה - תרגול 2

  21. קריאת מ"ה send – send.c מערכות הפעלה - תרגול 2

  22. קריאת מערכת הפעלה – send.c • send מתבצעת בצורה רצופה מבלי שתופרע ע"י מערכת ההפעלה • אולם, החלפת ההקשר יכולה לקרות ע"י reschedיזום • בדיקות תקינות כוללות בדיקה שאין כבר הודעה המחכה עבור התהליך המקבל • אם התהליך מחכה מעירים אותו ומבצעים resched מערכות הפעלה - תרגול 2

  23. קריאת מ"ה receive – receive.c מערכות הפעלה - תרגול 2

  24. קריאת מ"ה receive– receive.c • receive מתבצעת בצורה רצופה מבלי שתופרע ע"י מערכת ההפעלה • אולם, החלפת ההקשר יכולה לקרות ע"י reschedיזום • אם אין הודעה התהליך עובר למצב PRRECV ויוצא מהמעבד אחרי resched • האם הוא נמצא בתור כלשהו? איך יחזור לפעולה? • למה שומרים הודעה במשתנה לוקלי msg? מערכות הפעלה - תרגול 2

  25. קריאת מ"ה receiveclr – receiveclr.c מערכות הפעלה - תרגול 2

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

  27. פתרון למניעה הדדית ברמת המ"ה • ניתן לכבות את מנגנון הפסיקות (כיבוי IF) • במערכות המודרניות משתמשים בשיטה זו: • בקוד הפנימי של מערכת הפעלה • תוכניות קלט/פלט (כגון קריאה של USB או רשת) • הפתרון חסום ברמת האפליקציה מערכות הפעלה - תרגול 2

  28. מניעה הדדית באמצעות mutex • ראינו מימוש אפשרי של מניעה הדדית באמצעות הסמפורים • בדרך כלל הדבר נעשה ע"י מימוש מנגנון נעילות הקרוי mutex • מנגנון הנעילה מזוהה עם משאב משותף שעבורו רוצים למנוע גישה בו-זמנית • מנגנון הנעילות לא מבטיח שתהליך שנכנס לקטע קריטי לא ייעצר עד שיצא ממנו. הוא מבטיח שתהליכים אחרים לא יכנסו לקטע קריטי נעול מערכות הפעלה - תרגול 2

  29. מניעה הדדית באמצעות mutex • אם קטע קריטי נעול על ידי תהליך מסויים כל היתר לא יצליחו לעבור מנעול ויעצרו בכניסה לקטע קריטי • המנגנון לא מסוגל לכפות את עצמו על אף תהליך • התהליך חייב להיות מתוכנת לגשת לקטע קריטי דרך מנגנון הנעילות מערכות הפעלה - תרגול 2

  30. הפעלת mutex • שני מצבים – "פתוח" ו-"נעול" • התהליך שנכנס לקטע קריטי "נועל" (lock) את mutex, מבצע קטע קריטי ו"משחרר" (unlock)את mutex ביציאה • אם תהליך מנסה לנעול מנגנון נעילות נעול, הוא נעצר ומצטרף לתור הממתינים למנגנון הנעילות מערכות הפעלה - תרגול 2

  31. קריאות mutex נעילה: mutex_lock(&global_variable); שחרור: mutex_unlock(&global_variable); דוגמה: MUTEX_VAR mtx = MUTEX_VAR_INITIALIZER; mutex_lock(&mtx); critical_variable++; mutex_unlock(&mtx); מערכות הפעלה - תרגול 2

  32. מימוש מנגנון הנעילות • ניתן לממש את מנגנון הנעילות בעזרת סמפור • ניתן להשתמש בסמפור יחיד שהערך ההתחלתי של המונה שלו הוא 1. • נקצה עבור כל מנגנון הנעילות רשומה המכילה: • סטטוס של מנגנון – סגור או פתוח • מספר הסמפור שהוקצה • שדה המציין את הבעלים הזמניים של מנגנון מערכות הפעלה - תרגול 2

  33. הגדרת הרשומה – mutex.h מערכות הפעלה - תרגול 2

  34. mutex.c SYSCALL mutex_lock(MUTEX_REC_PTR *mutex_var) { int nsem; int ps, ans; disable(ps); if ((*mutex_var) == (MUTEX_REC_PTR)NULL) { nsem = screate(1); if (nsem == SYSERR) { restore(ps); return SYSERR; }; (*mutex_var) = (MUTEX_REC_PTR) getmem(sizeof(MUTEX_REC)); (*mutex_var)->nsem = nsem; } ans = wait((*mutex_var)->nsem); (*mutex_var)->pid = currpid; restore(ps); return ans; } מערכות הפעלה - תרגול 2

  35. mutex_lock • בנעילה ראשונה יוצרים רשומת mutex • מקצים סמפור עבור המנגנון ונשמוראת ה-sid שלו ברשומה • מחכים בתור לכניסה למנגנון הנעילה • מעדכנים את הפרטים של הבעלים הנוכחיים של mutex • משחזרים פסיקות. בפועל זה קורה פעמיים – בתוך screate וגם בתוך הקריאה עצמה מערכות הפעלה - תרגול 2

  36. mutex.c SYSCALL mutex_unlock(MUTEX_REC_PTR *mutex_var) { int ps; disable(ps); if ( ((*mutex_var) == (MUTEX_REC_PTR)NULL) || ((*mutex_var)->pid != currpid) ) return SYSERR; if ( isempty(semaph[(*mutex_var)->nsem].sqhead)) { sdelete((*mutex_var)->nsem); freemem((*mutex_var), sizeof(MUTEX_REC)); (*mutex_var) = MUTEX_VAR_INITIALIZER; restore(ps); return OK; } /* if */ signal((*mutex_var)->nsem); restore(ps); return OK; } /* mutex_unlock */ מערכות הפעלה - תרגול 2

  37. mutex_unlock • אם התור הוא ריק הרשומה משתחררת והסמפור נמחק • אם יש תהליכים המחכים בתור נקראת signal כדי לשחרר את התהליך הבא • התהליך משחרר נעילה ויוצא מקטע קריטי • התהליך המשוחרר נמצא באמצע פעולת lock. הוא רושם את עצמו כבעלים החדשים של mutex ומבצע קטע קריטי מערכות הפעלה - תרגול 2

  38. דוגמה:בנק • קיימים 2 חשבונות בנק • הכספים עוברים מחשבון לחשבון • אל המשתנים הגלובליים ניגשים שני תהליכים: • תהליך ראשון מעביר סכומים מחשבון לחשבון • תהליך שני מדפיס סה"כ כסף בשני החשבונות • הסה"כ צריך להיות קבוע. האם זה קורה באמת? מערכות הפעלה - תרגול 2

  39. ממוש 1 – testmu1.c volatile int bank[2] = {450, 600}; xmain() { resume(create(bank1,INITSTK, INITPRIO, "proc 1", 0) ); resume(create(bank2,INITSTK, INITPRIO, "proc 2", 0) ); } int bank1() { int sums[] = {100, -50, 150, -200}; int i=0, j, sum; while(1) { i++; i = i % 4; sum = sums[i]; bank[0] += sum; for(j=0; j < 32000; j++) ; bank[1] -= sum; } } int bank2() { int sum; int i= 0; while(1) { i++; i = i % 30000; sum = bank[0] + bank[1]; if ((sum != 1050)|| (i == 0)) printf("sum = %d\n", sum); } } מערכות הפעלה - תרגול 2

  40. testmu1.c • הסכום הלא מתאים מודפס בכל מקרה גם פעם ב-30000 מקרים אם הוא מתאים • המימוש לא מגן על המשאב המשותף עם מנגנון הנעילות • נראה גיוון מספרים בפלט מערכות הפעלה - תרגול 2

  41. testmu1.c - פלט sum = 850 sum = 850 sum = 850 sum = 1200 sum = 1200 sum = 1200 sum = 1200 sum = 1150 sum = 1150 sum = 1150 sum = 1150 sum = 1000 sum = 1000 sum = 1000 sum = 850 sum = 850 sum = 850 sum = 850 הפלט מכיל מספרים שונים מערכות הפעלה - תרגול 2

  42. ממוש 2 – testmu2.c volatile int bank[2] = {450, 600}; xmain() { resume(create(bank1,INITSTK, INITPRIO, "proc 1", 0) ); resume(create(bank2,INITSTK, INITPRIO, "proc 2", 0) ); } int bank1() { int sums[] = {100, -50, 150, -200}; int i=0, j, sum; while(1) { i++; i = i % 4; sum = sums[i]; mutex_lock(&mutex1); bank[0] += sum; bank[1] -= sum; mutex_unlock(&mutex1); } } int bank2() { int sum; int i= 0; while(1) { i++; i = i % 30000; mutex_lock(&mutex1); sum = bank[0] + bank[1]; mutex_unlock(&mutex1); if ((sum != 1050)|| (i == 0)) printf("sum = %d\n", sum); } } מערכות הפעלה - תרגול 2

More Related