2002נובמבר 1
סנכרון תהליכים וחוטיםProcess and Thread
Synchronization
חלק ראשון
2002נובמבר עמוד2
נושאים
מוטיבציההגדרותפיתרון כללימנעולים ותמיכתם בחומרה
2002נובמבר עמוד3
מוטיבציה
הנחותתקריאה/כתיבה של משתנה היא אטומי–פעולה אריתמטית על המשתנה אינה אטומית–
?לפעמים מי זוכהA ולפעמים B?לאהאם תמיד יש זוכההאם שניהם עשויים
אסינכרוניתkillכן, כאשר הפקודה לזכות?
int c = 0; // Global variable
Thread A: while (c < 10) c = c + 1; kill B; print “A wins”;
Thread B: while (c > -10) c = c - 1; kill A; print “B wins”;
2002נובמבר עמוד4
בעית יצרן/צרכן
הגדרותשני חוטים )יצרן וצרכן( רצים באותו מרחב זיכרון–מערך חסום )מעגלי( מכיל את העצמים המיוצרים– למקום הפנוי הבא במערך(pp)ליצרן מצביע –למקום הבא המכיל את העצם המוכן ( cp )לצרכן מצביע–
הבאcמספר העצמים המוכנים הוא –0n-1
cppp
c
2002נובמבר עמוד5
)המשך(בעית יצרן/צרכן
בעיותcעדכון בו זמנית )לא מוגן( של – יכול להיות גבוה )נמוך( מן הערך הנכוןcלכן ערכו של –
int c = 0; // Global variable
Producer: repeat while (c>=n) nop; buf[pp] = new item; pp = (pp+1) mod n; c = c + 1; until false;
Consumer: repeat while (c<1) nop; consume buf[cp]; cp = (cp+1) mod n; c = c - 1; until false;
2002נובמבר עמוד6
בעית החלב:את/ה
מסתכל במקררהולך לסופר
קונה חלבחוזר הביתה
מכניס חלב למקרר
:שותףמסתכל במקרר
הולך לסופרקונה חלב
חוזר הביתהמכניס חלב למקרר
!בעיה: יותר מדי חלב
2002נובמבר עמוד7
בעית החלב 1פיתרון
פיתרון: להשאיר פיתקה
בעיה: כל אחד קפץ לחדר לכתוב פתק ולא שםלב לכך שהשני השאיר פתק
מסתכל במקרראם אין חלב
אם אין פתקה השאר פתקה
קנה חלב הורד פתקה
2002נובמבר עמוד8
בעית החלב 2פיתרון
:השארת הפיתקה, בודקים האם לאחרפיתרון גם השותף השאיר פיתקה
!בעיה: קיים תסריט בו אף אחד לא יקנה חלב
Thread A: leave note A if (no note B) then if (no milk) then buy milk remove note A
Thread B: leave note B if (no note A) then if (no milk) then buy milk remove note B
2002נובמבר עמוד9
בעית החלב 3פיתרון
:שבירת הסימטריהפיתרון
,)במקרה של "תחרות" )שניהם משאירים פתק בו זמניתA יקנה חלב!
חסרונותרק לשני תהליכים–לא הוגן–
Thread A: leave note AX:while (note B) do nop if (no milk) then buy milk remove note A
Thread B: leave note BY:if (no note A) then if (no milk) then buy milk remove note B
2002נובמבר עמוד10
הגדרות
בגים בתכניות מקביליותבד"כ התכנית עובדת נכון–קיים תסריט בו התכנית לא עובדת נכון–
לרוב בגלל שבירה איזושהי הנחת אטומיות שאינה מתקיימת•
מרוץ(Race Condition)גישות בו-זמניות )כולל כתיבה( לאותו משתנה גלובלי–
בדוגמת בעית החלבהשארת פיתקה–בדיקה האם השותף השאיר פיתקה–
2002נובמבר עמוד11
)המשך(הגדרות
– מניעה הדדיתmutual exclusionמנגנונים המבטיחים שרק חוט אחד מבצע –
סדרת פעולות מסוימות בזמן נתוןאטומיות ביחס לחוטים אחרים•
– קטע קריטיcritical sectionקטע קוד שרק חוט אחד מבצע בזמן נתון–
יציאהלא קריטי קריטי
2002נובמבר עמוד12
)המשך(הגדרות
– אטומיותAtomicityבביצוע סדרת פקודות ע"י חוט אחד,חוטים אחרים אינם –
- סדרת הפקודות נראית כמו יכולים לראות תוצאות חלקיותפעולה אחת שאיננה ניתנת לחלוקה )"פעולה אטומית"(
ניתן להשיג בעזרת מנגנון של מניעה הדדית–דוגמא
העברת כספים מחשבון לחשבון–
לא נאפשר לחוטים אחרים לראות מצב בו הכסף נמשך –מחשבון א' אך לא הגיע לחשבון ב'
Thread A: account1:= account1 – sum; account2:= account2 + sum;
Thread B: if (account1+account2<min) then …
2002נובמבר עמוד13
תכונות של פתרון לבעיית הקטע הקריטי
חובהרק חוט אחד בקטע קריטי )מניעה הדדית(–אם יש בקשות להיכנס לקטע קריטי, אזי חוט אחד ייכנס –
(deadlockקיפאון – )אין
רצויחוט המבקש להיכנס לקטע קריטי בסופו של דבר יצליח –
(starvationהרעבה – )אין פעמים להיכנס nעבור כל זוג חוטים, אם הם יתחרו –
לקטע קריטי, הם יזכו מספר דומה של פעמים (fairness)
2002נובמבר עמוד14
Thread i: initially number[i]=0 number[i]=max{number[1],…,number[n]}+1; for all ji do wait until number[j]=0 or (number[j]>number[i])
critical section
number[i]=0 // Exit critical section
(bakery)אלגוריתם קופת חולים (1) לפיתרון בעית הקטע הקריטי
שימוש במספריםחוט נכנס לוקח מספר–חוט שמספרו הקטן ביותר נכנס לקטע הקריטי–
ניסיון ראשון
2002נובמבר עמוד15
(bakery)אלגוריתם קופת חולים (1) לפיתרון בעית מניעה הדדית
בעיה קוראים את המערך בו זמניתj ו-iחוט –שניהם "בוחרים" את אותו מספר–
!קיפאון
2002נובמבר עמוד16
(bakery)אלגוריתם קופת חולים (2) לפיתרון בעית מניעה הדדית
נשתמש במס' הזהות של התהליך כדילשבור סימטריה
Thread i: initially number[i]=0 number[i]=max{number[1],…,number[n]}+1; for all ji do wait until number[j]=0 or ()number[j],j)>(number[i],i)) // lexicographical // comparison
critical section
number[i]=0 // Exit critical section
2002נובמבר עמוד17
(bakery)אלגוריתם קופת חולים (2) לפיתרון בעית מניעה הדדית
בעיה( i>j ) קוראים את המערך בו זמניתj ו-iחוט – כותב את המספר, בודק את ערכו כנגד iחוט –
number( ונכנס לקטע הקריטי number[j] 0 עדיין)! ממשיך וגם הוא נכנס לקטע הקריטי!jחוט –
!אין מניעה הדדית מזדרז להיכנס (i)התהליך עם מספר זהות גבוה –
number[j] הספיק לכתוב את jלקטע הקריטי לפני ש-
2002נובמבר עמוד18
(bakery)אלגוריתם קופת חולים (3) לפיתרון בעית מניעה הדדית
נוודא שאין חוטים באמצע בחירת מספרלפני ביצוע ההשוואות
Thread i: initially number[i]=0 choosing[i]=true number[i]=max{number[1],…,number[n]}+1; choosing[i]=false
for all ji do wait until choosing[j]=false for all ji do wait until number[j]=0 or
()number[j],j)>(number[i],i))
critical section
number[i]=0 // Exit critical section
2002נובמבר עמוד19
(bakery)אלגוריתם קופת חולים (3) לפיתרון בעית מניעה הדדית
)והפתרון הוגן אין הרעבה )ולכן אין קיפאון הוכחה בתרגול–
פיתרון מסורבלהרבה פעולות, הרבה משתנים–
הפיתרון לא יעבוד בסביבות מרובותמעבדים
–Out of order executionקיימים אלגוריתמים אחריםבהמשך נלמד על פתרונות אחרים
2002נובמבר עמוד20
(locks)מנעולים
מבטיחים גישה בלעדית למידעבאמצעות שתי פונקציות
–lock_acquire)lock( פעולה חוסמת )אם – המנעול תפוס(
–lock_release )lock(משחרר את המנעול –
2002נובמבר עמוד21
– דוגמא(locks)מנעולים
דוגמא – בעית יצרן/צרכן
האם ניתן לוותר על הגנה של קריאתc-ב ?whileמה קורה במקרה של יותר מצרכן אחד?–
Producer: repeat while (c>n) nop; buf[pp] = new item; pp = (pp+1) mod n; lock_acquire(c_lock) c = c + 1; lock_release(c_lock) until false;
Consumer: repeat while (c<1) nop; consume buf[cp]; cp = (cp+1) mod n; lock_acquire(c_lock) c = c - 1; lock_release(c_lock) until false;
2002נובמבר עמוד22
lock_release(L): disableInterrupts() L := FREE enableInterrupts()
מימוש מנעולים
אטומיותמובטחת ע"י חסימת פסיקות–
Busy waitניתן למנוע ע"י ניהול תור החוטים המחכים–
?למה חשוב לאפשר פסיקות בתוך הלולאה?ומה קורה במערכות מרובות מעבדים
חסימת פסיקות אינה מבטיחה אטומיות...–דורש תמיכה מהחומרה לפקודות "חזקות" יותר–
lock_acquire(L): disableInterrupts() while LFREE do enableInterrupts() disableInterrupts() L := BUSY enableInterrupts()
2002נובמבר עמוד23
מימוש מנעוליםtest&setתמיכת חומרה
test&set)boolvar( והחזר ערך קודםtrueכתוב ערך –
–L = falseמנעול פנוי – –L = trueמנעול תפוס –
lock_release(L): L := false
lock_acquire(L): while test&set(L) do nop
2002נובמבר עמוד24
מימוש מנעוליםcompare&swapתמיכת חומרה
compare&swap)mem, r1, r2( r2, כתוב ערך r1 ערך זהה לרגיסטר (mem)אם בזיכרון –
והחזר הצלחה אחרת החזר ערך כישלון–
ניתן לממש מונה אטומי
lock_acquire(L): r1 = false r2 = true while not compare&swap(L, r1, r2)) do nop
lock_release(L): L := false
2002נובמבר עמוד25
מימוש מנעולים מודרניload-linked & store conditional
ממומש ברוב הארכיטקטורות החדישות–Compaq’s Alpha, IBM’s PowerPC, MIPS4000
צמד פקודות–LL)mem(קרא את ערך הזיכרון – –SC)mem, val(-אם לא היתה כתיבה ל – mem מאז
והחזר הצלחה val האחרון, כתוב ערך )LL)memה-)אחרת כשלון(
-יותר כח מאשר לcompare&swapניתן לזהות כתיבות עוקבות של אותו ערך –
2002נובמבר עמוד26
מימוש מנעוליםload-linked & store conditional
lock_acquire(L): success = false repeat LL(L) if not L then success = SC(L, true) until success
lock_release(L): L := false
2002נובמבר עמוד27
load-linked & store conditional
מתי חשוב לזהות כתיבות עוקבות שלאותו ערך?
ברשימה מקושרת, הוצאת האיבר הראשון–remove_first(head): element = NULLA:if headNULL then LL(head) next_head = head->next element = head if not SC(head, next_head) goto A; return element
Recommended