Download presentation
1
תיאום בין תהליכים: שיטות מתקדמות
שימוש בחומרה למימוש מנעולים מנגנוני מערכת הפעלה לתיאום: סמפורים, משתני תנאי
2
מימוש מנעולים: חסימת פסיקות
lock_acquire(L): disableInterrupts() while LFREE do enableInterrupts() L = BUSY lock_release(L): L = FREE חסימת פסיקות מונעת החלפת חוטים ומבטיחה פעולה אטומית על המנעול למה מאפשרים פסיקות בתוך הלולאה? queue lock: מונע busy wait באמצעות ניהול תור של החוטים המחכים... בהמשך ההרצאה נדבר על ניהול תורים... February 03 חגית עטיה ©
3
חסימת פסיקות? בעיות במערכת עם מעבד יחיד:
תוכנית מתרסקת כאשר הפסיקות חסומות. פסיקות חשובות הולכות לאיבוד. עיכוב בטיפול בפסיקות I/O גורם להרעת ביצועים. במערכות עם כמה מעבדים, לא די בחסימת פסיקות. חוטים יכולים לרוץ בו-זמנית (על מעבדים שונים) February 03 חגית עטיה ©
4
תמיכת חומרה במנעולים test&set(boolvar) lock_acquire(L):
L = false – מנעול פנוי L = true – מנעול תפוס lock_acquire(L): while test&set(L) do nop lock_release(L): L = false test&set(boolvar) כתוב ערך true והחזר ערך קודם February 03 חגית עטיה ©
5
תמיכת חומרה מתקדמת compare&swap(mem,r1,r2) ממומש בארכיטקטורות IA32.
אחרת החזר כישלון ממומש בארכיטקטורות IA32. load-linked / store conditional LL(mem) – קרא את הערך בכתובת הזיכרון mem. SC(mem,val) – אם לא היתה כתיבה ל-mem מאז ה- LL(mem) האחרון שלך, כתוב ערך val והחזר הצלחה (אחרת כשלון) ממומש בהרבה ארכיטקטורות חדישות HP’s Alpha, IBM’s PowerPC, MIPS4000 February 03 חגית עטיה ©
6
Spinlocks מימוש מנעול באמצעות busy waiting: מאוד בזבזני.
בדוק האם המנעול תפוס (על-ידי גישה למשתנה). אם המנעול תפוס, בדוק שנית. גם בקופת-חולים... מאוד בזבזני. חוט שמגלה כי המנעול תפוס מבזבז זמן cpu. בזמן הזה החוט שמחזיק במנעול לא יכול להתקדם. priority inversion: אם לחוט הממתין עדיפות גבוהה. הנזק אינו רק שחוט הממתין לא עושה עבודה משמעותית אלא גם שהחוט בעל המנעול לא מתקרב לשחרור המנעול. February 03 חגית עטיה ©
7
מנגנוני תיאום גבוהים יותר
לנהל תור של החוטים הממתינים. ☼ נמצא במנגנוני תיאום עיליים: סמפורים משתני תנאי ... מוניטורים February 03 חגית עטיה ©
8
סמפור שני שדות: ערך שלם לא-שלילי תור של חוטים / תהליכים ממתינים
[Dykstra, 1968] February 03 חגית עטיה ©
9
פעולות על סמפור wait(semaphore) signal(semaphore)
מקטין את ערך המונה ב-1 ממתינים עד שערך המונה אינו שלילי. נקרא גם P(), proben signal(semaphore) מגדיל את ערך המונה ב-1 משחרר את אחד הממתינים. נקרא גם V(), verhogen February 03 חגית עטיה ©
10
יותר מידי חלב עם סמפורים
קוד זהה לשני החוטים. סמפור OKToBuyMilk, בהתחלה 1. wait( OKToBuyMilk); if ( NoMilk ) { Buy Milk; // critical section } signal( OKToBuyMilk); אם ערך הסמפור > 0 ניתן להכנס לסמפור. אם ערך הסמפור ≤ 0 הסמפור תפוס, וערכו הוא מספר הממתינים מה המשמעות של ערך חיובי? February 03 חגית עטיה ©
11
סמפור בינארי וסמפור מונה
ערך התחלתי =1; זה גם הערך המקסימלי. מאפשר גישה בלעדית למשאב (בדומה למנעול). סמפור מונה ערך התחלתי N>0. שולט על משאב עם N עותקים זהים. חוט יכול להיכנס לסמפור כל עוד יש עותק פנוי של המשאב. February 03 חגית עטיה ©
12
דוגמה: בעיית יצרן / צרכן
שני חוטים רצים באותו מרחב זיכרון היצרן מיצר אלמנטים לטיפול (למשל, משימות) הצרכן מטפל באלמנטים (למשל, מבצע את המשימות) מערך חסום (מעגלי) מכיל את העצמים המיוצרים. n-1 cp pp c האלמנט המוכן הבא המקום הפנוי הבא מספר האלמנטים המוכנים ידוע גם כבעיית החוצץ החסום: bounded buffer problem. February 03 חגית עטיה ©
13
פתרון לבעיית יצרן / צרכן?
global variable int c = 0; Producer: repeat wait until (c ≥ 1); buff[pp] = new item; pp = (pp+1) mod n; c = c + 1; until false; Consumer: repeat wait until (c ≥ 1); consume buff[cp]; cp = (cp+1) mod n; c = c - 1; until false; ואם ניגשים בו-זמנית ל-c??? February 03 חגית עטיה ©
14
יצרן / צרכן עם סמפורים semaphore freeSpace, initially N
Semaphore availItems, intiailly 0 Producer: repeat wait( freeSpace); buff[pp] = new item; pp = (pp+1) mod n; signal( availItems); until false; מספר המקומות הפנויים מספר האיברים המוכנים Consumer: repeat wait( availItems); consume buff[cp]; cp = (cp+1) mod n; signal( freeSpace); until false; חוסר מבניות: החוט ה-"נועל" סמפור אינו אותו חוט ש-"משחרר" אותו February 03 חגית עטיה ©
15
דוגמה: קוראים/כותבים חוטים קוראים וחוטים כותבים
מספר חוטים יכולים לקרוא בו-זמנית. כאשר חוט כותב, אסור שחוטים אחרים יכתבו ו/או יקראו. טבלת גישה Reader Writer אפשר לוותר על חלק מהדוגמאות. February 03 חגית עטיה ©
16
קוראים / כותבים עם סמפורים
semaphore sRead, initially 1 semaphore sWrite, Writer: wait(sWrite) [Write] signal(sWrite) מגן על מונה מספר הקוראים מניעה הדדית בין קוראים לבין כותבים Reader: wait(sRead) r:=r+1 if r=1 then wait(sWrite) signal( sRead) [Read] wait( sRead) r:=r-1 if r=0 then signal(sWrite) ל sRead יש תפקיד נוסף... שימוש יותר מובנה: החוט שנועל את sRead גם משחרר אותו, ומה לגבי sWrite? אם מימוש הסמפורים הוגן (fifo), האם הדוגמא מבטיחה הוגנות? February 03 חגית עטיה ©
17
מימוש (תיאורטי) של סמפורים?
struct semaphore_t { int value; queue waitQ; } void wait(semaphore_t *s){ s->value--; if (s->value < 0){ enQ(self, &s->waitQ); block } void signal(semaphore_t *s){ s->value++; if (s->value <= 0){ P = deQ( &s->waitQ); wakeup(P) } } February 03 חגית עטיה ©
18
מימוש של סמפורים: תיקון
struct semaphore_t { int value; queue waitQ; lock_t l; } void wait(semaphore_t *s){ lock(&s->l) ; s->value--; if (s->value < 0){ enQ(self, &s->waitQ); unlock(&s->l) ; block } else unlock(&s->l) ; void signal(semaphore_t *s){ lock(&s->l) ; s->value++; if (s->value <= 0){ P = deQ( &s->waitQ); wakeup(P) } unlock(&s->l) ; } February 03 חגית עטיה ©
19
היה busy-waiting? עדיין יש נעילה: על הגישה לתור השייך לסמפור.
...אבל הקטע הקריטי קצר: רק לשים / להוריד אלמנט מתור. אפשר לתכנת כך שתהיה עבודה בו-זמנית בשני הקצוות של תור לא-ריק. ההשלכות של busy-waiting מוקטנות. February 03 חגית עטיה ©
20
גרף תלויות תהליכים P1… PN מבצעים חישוב
תהליך PA ממתין לתוצאות כל החישובים לפני שיוכל להתחיל לפעול PA מחשב את ממוצע התוצאות. כיצד ניתן להבטיח שPA יתחיל לפעול רק לאחר שכל האחרים יסיימו? סדר הסיום לא ידוע מראש. PA P1 P2 P3 PN February 03 חגית עטיה ©
21
ייצוג גרף תלויות עם סמפורים
תהליך PA ממתין על-פי מספר התהליכים בהם הוא תלוי. תהליך שמסיים מבצע signal. האם האלגוריתם יעבוד גם אם Pi כלשהו יסיים ויבצע signal לפני שPA קרא ל- wait? wait(s) wait(s) wait(s) wait(s) Go! PA P1 P2 P3 PN signal(s) signal(s) signal(s) signal(s) February 03 חגית עטיה ©
22
גרפי תלויות אחרים לפעמים המצב הוא הפוך. ייתכנו גם מצבים מורכבים בהרבה.
N תהליכים ממתינים לתהליך אחד לפני שיוכלו להתחיל לפעול. ייתכנו גם מצבים מורכבים בהרבה. לא תמיד מספיק סמפור בודד. P1 P2 P3 PN PA P0 P8 P9 P10 P17 P1 P2 P3 P7 P18 P19 February 03 חגית עטיה ©
23
חסרונות של סמפורים לא מפרידים: קושי במימוש.
נעילה. המתנה. ניהול משאבים. קושי במימוש. רעיון מודרני יותר: נקודות מפגש במשתני תנאי... February 03 חגית עטיה ©
24
פעולות על משתני תנאי wait(cond,&lock): signal(cond): broadcast(cond):
שחרר את המנעול (חייב להחזיק בו). המתן לפעולת signal. המתן למנעול (כשחוזר מחזיק במנעול). signal(cond): הער את אחד הממתינים ל cond, אשר עובר להמתין למנעול. הולך לאיבוד אם אין ממתינים. broadcast(cond): הער את כל התהליכים הממתינים. עוברים להמתין למנעול. February 03 חגית עטיה ©
25
משתני תנאי: הערות כאשר תהליך מקבל signal הוא מפסיק להמתין ועובר למצב ready, אך לא בהכרח רץ. mesa-style. משתני תנאי הולכים נפלא עם מנעולים. wait(cond,&lock) קודם משחררת את המנעול lock. בניגוד לסמפורים, signal לא זוכר היסטוריה. signal(cond) הולך לאיבוד אם אין ממתינים על cond. February 03 חגית עטיה ©
26
דוגמא – מימוש תור ממתינים כאשר התור ריק. נעילה להגן על הגישה לנתונים.
lock QLock ; condition notEmpty; Enqueue (item): lock_acquire( QLock) put item on queue signal(notEmpty,&QLock) lock_release( QLock) Dequeue (item): while stack empty wait(notEmpty ,&QLock) remove item from stack ממתינים כאשר התור ריק. נעילה להגן על הגישה לנתונים. קטע קריטי קצר. משתנה תנאי מאפשר לחכות עד שיתווסף איבר לתור, מבלי לבצע busy-wait. למה צריך while? משתני תנאי הולכים טוב עם מנעולי mutex. February 03 חגית עטיה ©
27
יצרן / צרכן עם משתני תנאי
condition not_full, not_empty; lock bLock; producer: lock_acquire(bLock); while(buffer is full) wait(not_full,&bLock); add item to buffer ; signal(not_empty); lock_release(bLock); consumer: lock_acquire(bLock); while (buffer is empty) wait(not_empty,&bLock); get item from buffer signal(not_full); lock_release(bLock); February 03 חגית עטיה ©
28
משתני תנאי + מנעול מוניטור
ההקשר המקורי של משתני תנאי [C.A.R. Hoare, 1974] אובייקט (במובן של שפת-תכנות object-oriented), הכולל פרוצדורת אתחול וגישה. הגישה לאובייקט מקנה שליטה במנעול (באופן לא-מפורש) שליחת signal משחררת את המנעול ומעבירה את השליטה בו למקבל ה signal. תמיכה של שפת-תכנות (למשל ב Java). זהו רגע של היסטוריה. ההתנהגות שונה במקצת, וידועה בשם Hoare-style. February 03 חגית עטיה ©
29
מנגנוני תיאום ב POSIX אובייקטים לתיאום mutex locks (pthread_mutex)
נמצאים בזיכרון המשותף. נגישים לחוטים של תהליכים שונים. mutex locks (pthread_mutex) יצירה, השמדה. lock, unlock, trylock. condition variables (pthread_cond) wait, signal, broadcast. trylock בודק אם המנעול פנוי. יש הרחבה לסמפורים אבל לא סטנדרטית. עוד בתרגול... February 03 חגית עטיה ©
30
מנגנוני תיאום ב-Windows NT
כל רכיב במערכת ההפעלה הוא אובייקט ניתן להמתין ו/או לשחרר אובייקטים מיוחדים mutex– מנעול הוגן event – משתנה תנאי (עם אפשרות ל-broadcast כדי להעיר את כל הממתינים) semaphore – סמפור מונה, לא הוגן critical section – light-weight mutex המיועד לחוטים באותו תהליך February 03 חגית עטיה ©
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.