27
רררררר2002 1 רררררר ררררררר ררררררProcess and Thread Synchronization ןןן ןןןןן

נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

  • View
    226

  • Download
    5

Embed Size (px)

Citation preview

Page 1: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר 1

סנכרון תהליכים וחוטיםProcess and Thread

Synchronization

חלק ראשון

Page 2: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד2

נושאים

מוטיבציההגדרותפיתרון כללימנעולים ותמיכתם בחומרה

Page 3: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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”;

Page 4: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד4

בעית יצרן/צרכן

הגדרותשני חוטים )יצרן וצרכן( רצים באותו מרחב זיכרון–מערך חסום )מעגלי( מכיל את העצמים המיוצרים– למקום הפנוי הבא במערך(pp)ליצרן מצביע –למקום הבא המכיל את העצם המוכן ( cp )לצרכן מצביע–

הבאcמספר העצמים המוכנים הוא –0n-1

cppp

c

Page 5: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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;

Page 6: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד6

בעית החלב:את/ה

מסתכל במקררהולך לסופר

קונה חלבחוזר הביתה

מכניס חלב למקרר

:שותףמסתכל במקרר

הולך לסופרקונה חלב

חוזר הביתהמכניס חלב למקרר

!בעיה: יותר מדי חלב

Page 7: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד7

בעית החלב 1פיתרון

פיתרון: להשאיר פיתקה

בעיה: כל אחד קפץ לחדר לכתוב פתק ולא שםלב לכך שהשני השאיר פתק

מסתכל במקרראם אין חלב

אם אין פתקה השאר פתקה

קנה חלב הורד פתקה

Page 8: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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

Page 9: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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

Page 10: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד10

הגדרות

בגים בתכניות מקביליותבד"כ התכנית עובדת נכון–קיים תסריט בו התכנית לא עובדת נכון–

לרוב בגלל שבירה איזושהי הנחת אטומיות שאינה מתקיימת•

מרוץ(Race Condition)גישות בו-זמניות )כולל כתיבה( לאותו משתנה גלובלי–

בדוגמת בעית החלבהשארת פיתקה–בדיקה האם השותף השאיר פיתקה–

Page 11: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד11

)המשך(הגדרות

– מניעה הדדיתmutual exclusionמנגנונים המבטיחים שרק חוט אחד מבצע –

סדרת פעולות מסוימות בזמן נתוןאטומיות ביחס לחוטים אחרים•

– קטע קריטיcritical sectionקטע קוד שרק חוט אחד מבצע בזמן נתון–

יציאהלא קריטי קריטי

Page 12: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד12

)המשך(הגדרות

– אטומיותAtomicityבביצוע סדרת פקודות ע"י חוט אחד,חוטים אחרים אינם –

- סדרת הפקודות נראית כמו יכולים לראות תוצאות חלקיותפעולה אחת שאיננה ניתנת לחלוקה )"פעולה אטומית"(

ניתן להשיג בעזרת מנגנון של מניעה הדדית–דוגמא

העברת כספים מחשבון לחשבון–

לא נאפשר לחוטים אחרים לראות מצב בו הכסף נמשך –מחשבון א' אך לא הגיע לחשבון ב'

Thread A: account1:= account1 – sum; account2:= account2 + sum;

Thread B: if (account1+account2<min) then …

Page 13: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד13

תכונות של פתרון לבעיית הקטע הקריטי

חובהרק חוט אחד בקטע קריטי )מניעה הדדית(–אם יש בקשות להיכנס לקטע קריטי, אזי חוט אחד ייכנס –

(deadlockקיפאון – )אין

רצויחוט המבקש להיכנס לקטע קריטי בסופו של דבר יצליח –

(starvationהרעבה – )אין פעמים להיכנס nעבור כל זוג חוטים, אם הם יתחרו –

לקטע קריטי, הם יזכו מספר דומה של פעמים (fairness)

Page 14: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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) לפיתרון בעית הקטע הקריטי

שימוש במספריםחוט נכנס לוקח מספר–חוט שמספרו הקטן ביותר נכנס לקטע הקריטי–

ניסיון ראשון

Page 15: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד15

(bakery)אלגוריתם קופת חולים (1) לפיתרון בעית מניעה הדדית

בעיה קוראים את המערך בו זמניתj ו-iחוט –שניהם "בוחרים" את אותו מספר–

!קיפאון

Page 16: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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

Page 17: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד17

(bakery)אלגוריתם קופת חולים (2) לפיתרון בעית מניעה הדדית

בעיה( i>j ) קוראים את המערך בו זמניתj ו-iחוט – כותב את המספר, בודק את ערכו כנגד iחוט –

number( ונכנס לקטע הקריטי number[j] 0 עדיין)! ממשיך וגם הוא נכנס לקטע הקריטי!jחוט –

!אין מניעה הדדית מזדרז להיכנס (i)התהליך עם מספר זהות גבוה –

number[j] הספיק לכתוב את jלקטע הקריטי לפני ש-

Page 18: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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

Page 19: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד19

(bakery)אלגוריתם קופת חולים (3) לפיתרון בעית מניעה הדדית

)והפתרון הוגן אין הרעבה )ולכן אין קיפאון הוכחה בתרגול–

פיתרון מסורבלהרבה פעולות, הרבה משתנים–

הפיתרון לא יעבוד בסביבות מרובותמעבדים

–Out of order executionקיימים אלגוריתמים אחריםבהמשך נלמד על פתרונות אחרים

Page 20: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד20

(locks)מנעולים

מבטיחים גישה בלעדית למידעבאמצעות שתי פונקציות

–lock_acquire)lock( פעולה חוסמת )אם – המנעול תפוס(

–lock_release )lock(משחרר את המנעול –

Page 21: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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;

Page 22: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד22

lock_release(L): disableInterrupts() L := FREE enableInterrupts()

מימוש מנעולים

אטומיותמובטחת ע"י חסימת פסיקות–

Busy waitניתן למנוע ע"י ניהול תור החוטים המחכים–

?למה חשוב לאפשר פסיקות בתוך הלולאה?ומה קורה במערכות מרובות מעבדים

חסימת פסיקות אינה מבטיחה אטומיות...–דורש תמיכה מהחומרה לפקודות "חזקות" יותר–

lock_acquire(L): disableInterrupts() while LFREE do enableInterrupts() disableInterrupts() L := BUSY enableInterrupts()

Page 23: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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

Page 24: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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

Page 25: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

2002נובמבר עמוד25

מימוש מנעולים מודרניload-linked & store conditional

ממומש ברוב הארכיטקטורות החדישות–Compaq’s Alpha, IBM’s PowerPC, MIPS4000

צמד פקודות–LL)mem(קרא את ערך הזיכרון – –SC)mem, val(-אם לא היתה כתיבה ל – mem מאז

והחזר הצלחה val האחרון, כתוב ערך )LL)memה-)אחרת כשלון(

-יותר כח מאשר לcompare&swapניתן לזהות כתיבות עוקבות של אותו ערך –

Page 26: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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

Page 27: נובמבר 20021 סנכרון תהליכים וחוטים Process and Thread Synchronization חלק ראשון

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