os - processes Flashcards
על מעבד אחד יכול לרוץ רק תהליך אחד כל פעם. כדי לגרום למקביליות מדומה
ש להחליף מהר בין התהליכים. החלפת התהליכים כרוכה בתקורה (overhead), כיוון שבכל פעם יש לשמור את המצב של התהליך הנוכחי ולטעון את המצב של התהליך הבא.
כל תהליך נמצא באחד מ-3 מצבים
רץ- התהליך רץ כעת. מוכן- התהליך איננו רץ כעת, אך מוכן לריצה כאשר מערכת ההפעלה תזמן אותו. חסום- איננו מוכן כלל לריצה (נשים לב שתהליך אינו מודע להשהייתו!), מחכה לאירוע כלשהו (כגון I/O), המונע ממנו במילא לרוץ. בזמן שהתהליך החסום מחכה, ניתן להריץ תהליכים אחרים (מה שגורם למקביליות אמיתית).
כל תהליך מקבל יחידת זמן המחולקת ל-quantums
איך נבחר quantums?
quantum קטן משפר מקביליות מדומה (עד מספר מסוים, יכול להיות שהתקורה תיקח יותר מדי זמן ותפגע במקביליות), וכי quantum גדול משפר מקביליות אמיתית (יש יותר סיכוי להגיע ל-I/O בפרק הזמן שהוקצה) ואת ניצולת המעבד.
נשים לב שמספר רב של תהליכים משפר עד מידה מסוימת את רמת המקביליות המדומה, אך משלב מסוים מוריד אותה
יתרונות של תהליכונים על תהליכים
זמן היצירה של תהליכון קטן ביחס לזמן היצירה של תהליך (אין צורך ליצור מפת זיכרון), כמו גם זמן סיומו.
זמן ההחלפה בין תהליכונים (ברמת המעבד) קצר מזמן ההחלפה בין תהליכים.
תקשורת בין תהליך מארח יכולה להתבצע ללא התערבותו של גרעין מערכת ההפעלה, מכיוון שתהליכונים אלה משתפים זיכרון, קבצים וכו’
לכל התהליכונים הנמצאים באותו תהליך יש המאפיינים הבאים:
מצב התהליכון (running, ready, blocked).
מצב הרגיסטרים של המעבד.
מחסנית נפרדת עבור כל תהליכון.
אפשרות גישה לזיכרון ולמשאבים המשותפים בתוך התהליך.
מימוש תהליכונים במרחב המשתמש- ניהול התהליכונים מתבצע במרחב של התהליך המארח, כך שגרעין מערכת ההפעלה לא מודע לקיומם. התהליך המארח יהיה אחראי על תזמון התהליכונים (למשל באמצעות ספריות)-שוב, במצב משתמש. יתרונות וחסרונות
מימוש תהליכונים במרחב המשתמש- ניהול התהליכונים מתבצע במרחב של התהליך המארח, כך שגרעין מערכת ההפעלה לא מודע לקיומם. התהליך המארח יהיה אחראי על תזמון התהליכונים (למשל באמצעות ספריות)-שוב, במצב משתמש. יתרונות: החלפת תהליכונים מהירה יותר (אין צורך לעבור למצב מיוחס), תזמון התהליכונים לפי אלגוריתם תזמון ידוע מראש. חסרונות: התהליך המארח (וכל התהליכונים שבו) עלולים להיחסם, בעקבות קריאה שמבצע אחד התהליכונים בתוך התהליך. לא יהיה ניתן לנצל ריבוי מעבדים (כיוון שמערכת ההפעלה לא מודעת לתהליכונים כלל, לא ניתן להפעילם במקביל על מעבדים שונים).
מימוש תהליכונים בגרעין המערכת- כל מלאכת ניהול התהליכונים מתבצעת על ידי גרעין מערכת ההפעלה.
יתרונות: אין חסרונות של מימוש תהליכונים במרחב משתמש. חסרונות: בזבוז הזמן הכרוך במעבר ממצב משתמש למצב מיוחס.
מה הוא קטע קריטי
קטע קוד בעל משאב משותף, כל שהעברת זמן המעבד לתהליך אחר בזמן שתהליך כלשהו משתמש במשאב המשותף, עלול לגרום לתוצאות לא רצויות. קטע בו יכולים להיווצר מצבי מרוץ- מצב שבו מספר תהליכים עובדים על מידע המשותף לכולם, והתוצאה הסופית של פעולתם תלויה בסדר המדויק של הקצאת המעבד להם. זמן שהייה בקטע קריטי הוא סופי.
מה היא מניעה הדדית
אם תהליך אחד משתמש במשאב מסוים, שום תהליך אחר לא יכול לקבל גישה למשאב זה לפני שהתהליך שמשתמש במשאב ישחרר אותו
ארבעת התנאים לפתרון סביר של בעיית המרוץ
שני תהליכים לא ישהו בו-זמנית בתוך הקטע הקריטי (תנאי מחייב לפתרון, לאו דווקא סביר).
הפתרון לא יסתמך על השערות הקשורות למהירות או למספר המעבדים.
תהליך מחוץ לקטע הקריטי לא ימנע מתהליך אחר להיכנס לקטע הקריטי (אין להכניס במשאב בלי להיכנס קודם לקטע קריטי).
התהליך לא ימתין לנצח כדי להיכנס לקטע קריטי.
המתנה פעילה (busy waiting)
היא מצב בו תהליך מקבל את המעבד ומנצל את מלוא הזמן המוקצב לו, אך איננו מתקדם כלל. המתנה זו, בדרך כלל, מתבצעת ביוזמת התהליך כדי לחכות לאירוע מסוים. המתנה פעילה גורמת לבזבוז של זמן עיבוד.
5 פתרונות הממומשים על ידי busy waiting:
מניעת פסיקות (מניעת content switch)
משתני נעילה
פתרון התור
הפתרון של פיטרסון
פקודת TSL
המתנה פעילה - מניעת פסיקות
מניעת פסיקות (מניעת content switch) לפני כניסת תהליך לקטע הקריטי, והחזרתן אחרי יציאתו משם. מניעת פסיקות גורמת לכך שהמעבד לא עובר מתהליך לתהליך ולכן אין חשש שתהליך אחר יכול להימצא בקטע הקריטי. למרות פשטות ההצעה, יש לה 3 חסרונות מהותיים:
אין לתת למשתמש את האפשרות לבטל פסיקות! עלול לגרום לתקיעת המחשב אם המשתמש שוכח להחזיר את הפסיקות (או עושה זאת בכוונת תחילה).
חסימת הפסיקות לפרק זמן ארוך יכולה להביא לתופעות לא נעימות - ירידה ברמת
המקביליות של מערכת ההפעלה
חסימה של פסיקות תקפה לגבי מעבד אחד בלבד
המתנה פעילה משתני נעילה
התהליך נועל את המנעול (שם במנעול ערך 1) לפני כניסה לקטע הקריטי, ופותח אותו אחרי היציאה ממנו (שם במנעול ערך 0). הבעיה בפתרון זה היא שקריאת ערך המנעול (בדיקה אם המנעול פתוח) ונעילתו (השמת 1 בערך המנעול) הן שתי פעולות שונות, שעלול להתבצע ביניהן content switch (הבדיקה והעדכון של משתנה הנעילה הופך לקטע קריטי בעצמו), ואז כמה תהליכים יוכלו להיכנס ביחד אל הקטע הקריטי למרות השימוש במנעול.
המתנה פעילה פתרון התור
עבור מספר תהליכים- כל תהליך מקבל ערך מפתח אחר, ותפקידו בעת יציאתו מן הקטע הקריטי לתת את התור לתהליך הבא אחריו (מבחינת סדר שנקבע מראש). זהו פתרון לבעיית המרוץ, אם כי זהו לא פתרון סביר- נניח שתהליך אחד נותן את תורו לתהליך שבא אחריו, שכלל לא מעוניין להיכנס אל הקטע הקריטי. התהליך הקודם שרוצה להיכנס שוב יאלץ לחכות עד שהתהליך שתורו להיכנס באמת ירצה להיכנס. דבר זה בא בסתירה לתנאי מספר 3 של פתרון סביר- תהליך מחוץ לקטע הקריטי לא ימנע מתהליך אחר להיכנס אליו. עלולה להיווצר כאן הרעבה של תהליכים.
המתנה פעילה הפתרון של פיטרסון
פתרון זה מתבסס על פתרון התור, אך הפעם מוסיף משתנה הבודק האם התהליך בכלל מעוניין להיכנס אל הקטע הקריטי (מה שפותר את הבעיה של פתרון התור). מי שמגיע אחרון אל הקטע הקריטי נאלץ לחכות שיתר התהליכים יסיימו את שהייתם בו (הפתרון הוגן). הפתרון של פיטרסון הוא פתרון סביר לבעיית המרוץ. פתרון זה תקף רק עבור 2 תהליכים!
המתנה פעילה פקודת TSL
הגדרת מספר פעולות כפעולה אטומית (הוראה שמתבצעת כצעד אחד שלא ניתן להפרידו לשלבים, לא ניתן לעשות content switch באמצע), כלומר, מנעול שיובטח שינעל בפעולה אטומית אחת. ביצוע הוראת TSL נועל את ערוץ הזיכרון למשך זמן ביצוע ההוראה, מה שמאפשר פתרון לבעיית המרוץ, אך עלולה להיווצר הרעבה של תהליכים כיוון ש-TSL אינו מסדיר את אופן הכניסה של תהליכים לקטע הקריטי (פתרון לא סביר במקרה של מספר תהליכים, בגלל תנאי 4, אך עבור שני תהליכים בלבד, הפתרון אכן סביר).
פתרונות שלא ממומשים על ידי busy waiting
נרצה לקבל פתרון העונה על הכללים הבאים:
הוא מקיים את ארבעת התנאים של פתרון סביר למספר תהליכים.
הוא אינו גורם למתנה פעילה.
הוא מסדיר את אופן הטיפול בתהליכים שרצו להיכנס לקטע הקריטי ולא יכלו לעשות זאת מכיוון שהקטע הקריטי היה תפוס.
הוא אינו מצריך זיהוי מצבים הדורשים היפוך עדיפויות (דוגמה לכלל זה בעמוד 65 במדריך).
5 פתרונות שלא ממומשים על ידי busy waiting
הרדמה והערה
סמפורים
מנעולים (mutexes)
מבני פיקוח (monitors)
העברת הודעות (message passing)
פתרונות שלא ממומשים על ידי busy waiting - הרדמה והערה
כל תהליך יוכל להשהות את עצמו על ידי קריאת המערכת SLEEP ולהתעורר כאשר תהליך אחר מבצע קריאת מערכת WAKEUP (עם מזהה של התהליך אותו יש להעיר). התהליכים שמבצעים קריאת SLEEP נכנסים למצב חסום (המתנה זו אינה מעסיקה את המעבד). מערכת ההפעלה יכולה לנהל תור של תהליכים רדומים ובכך להסדיר את אופן כניסתם של תהליכים לקטע הקריטי. הבעיה בפתרון זה היא שקריאת WAKEUP עלולה ללכת לאיבוד (נניח, כאשר קורה content switch בין בדיקת התנאי השואל האם על התהליך להעיר תהליך אחר לבין הערתו בפועל. אובדן הקריאה WAKEUP עלול לגרום לתקיעת המערכת).
פתרונות שלא ממומשים על ידי busy waiting - סמפורים
דומה מאוד לפתרון ה-SLEEP&WAKEUP, רק שהפעם שומרים מונה השומר את מספר ה-WAKEUP שהתבצעו, וגם בודקים האם התהליך התעורר. פה, מחליפים את הפעולות SLEEP ו-WAKEUP בפעולות down ו-up בהתאמה. בכל פעם שמתבצעת פקודת up, בודקים האם יש תהליכים במצב down (תהליכים שנרדמו על הסמפור). אם ישנם תהליכים כאלה, מעירים את התהליך הראשון בתור. אם אין, “שומרים” את ה-up לאחר כך (בכל פעם שיש להרדים תהליך, בודקים קודם האם יש up ספייר). המשתנה המונה את מספר ה-up שטרם נוצלו נקרא סמפור, והוא מנגנון מיוחד המסופק על ידי מערכת ההפעלה. יש לציין שהפעולות up ו-down חייבות להיות אטומיות.
פתרונות שלא ממומשים על ידי busy waiting - מנעולים (mutexes)
דומה מאוד לשימוש בסמפור בינארי (סמפור המאותחל בערך 1), אך יעיל יותר כיוון שלא נדרש עבורו מעבר בין רמת המשתמש לרמת הגרעין
פתרונות שלא ממומשים על ידי busy waiting - מבני פיקוח (monitors)
ספרייה של פונקציות, משתנים ומבני נתונים המוגדרים יחד במבנה של שפת תכנות. שפת התכנות היא זו שמבטיחה שתהליכים הקוראים לפונקציות המוגדרות במבנה הפיקוח מממשים מניעה הדדית. כך, כל האחריות ליישום הטכני של פתרון בעיית המניעה ההדדית עוברת אל הקומפיילר. בעקבות כך, יש פחות סיכוי לטעויות, בהשוואה לשימוש בסמפורים ובמנעולים. גם כאן נגדיר שתי פעולות מיוחדות: signal(c), מעירה אחד מהתהליכים שהיה חסום על ידי המוניטור על התנאי c. wait(c), גורמת להשהיית תהליך כל עוד התנאי c לא התקיים. המוניטור מבטיח שלאחר הקריאה ל-wait אחד התהליכים שהיה חסום על קטע קריטי יוכל להיכנס אליו.
פתרונות שלא ממומשים על ידי busy waiting - העברת הודעות (message passing)
ישנן שתי פקודות: send(destination, &m), ששולחת את ההודעה m ליעד נתון, ו-receive(source, &m), המקבלת הודעה ממקור נתון. השליחה של הודעות יכולה להיות שליחה שחוסמת את התהליך המקבל, אם הוא מחכה להודעה שטרם קיימת (נחסם עד להגעתה). ניתן להשתמש בשיטת המיעון הישיר, כך שכל תהליך השולח הודעה מחויב לציין את היעד (מזהה של תהליך), או בשיטת המיעון העקיף, שכל הודעה מועברת לתחנת ביניים, הנקראת תיבת דואר (mail box), שאליה מתקבלות הודעות וממנה מושכים הודעות. נשים לב ששיטה זו מתאימה גם למערכות מבוזרות, כלומר ניתן להעביר הודעות בין שני מעבדים או מחשבים שונים (בשונה מיתר השיטות).