מערכות הפעלה
Download
Report
Transcript מערכות הפעלה
מערכות הפעלה
תרגול – 6מימוש סינכרון תהליכים
מה בתכנית?
מימוש סנכרון
תהליכים בXINU-
Mutexes
2
מערכות הפעלה -תרגול 2
אפריל 15
אמצעי תקשורת וסינכרון
סמפור
wait(s)/signal(s)
שליחת הודעות
send(pid, msg)/receive()
( mutex מניעה הדדית)
3
מערכות הפעלה -תרגול 2
אפריל 15
מימוש סמפורים
מצב התהליך – PRWAIT
התהליך המחכה נמצא במצב PRWAITהמיוחד לסמפורים
תור לכל סמפור
לכל סמפור נשמר תור FIFOשל התהליכים המחכים לו ,כך
ש signal-יוכל לשחרר את הראשון שבהם ,ולהעבירו לתור ה-
ready
טבלת סמפורים semaphעם כניסות מסוג sentry
כל כניסה מכילה מונה ,מצביעים לתור (בטבלת )qודגל הכניסה
()SFREE/SUSED
ערך מזהה הסמפור sidהוא האינדקס של כניסתו בטבלת
הסמפורים
4
מערכות הפעלה -תרגול 2
אפריל 15
מימוש סמפורים – sem.h
5
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה wait.c – wait
6
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה wait
ביצוע waitלא מופרע באמצע ע"י מערכת
ההפעלה .הגנה באמצעות .disable/restoreאולם
החלפת הקשר היא אפשרית גם באמצע עקב
reschedיזום
לא ניתן לבצע waitעל סמפור שלא נוצר ,או שכבר
שוחרר
הכנסה לסוף תור הסמפור (כלומר )FIFO
הקריאה ל resched-הכרחית
7
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה signal.c – signal
8
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה signal
9
ביצוע signalלא מופרע באמצע ע"י מערכת ההפעלה.
הגנה באמצעות .disable/restoreאולם החלפת הקשר
היא אפשרית גם באמצע עקב reschedיזום
לא ניתן לבצע signalעל סמפור שלא נוצר ,או שכבר
שוחרר
ההוצאה מראש תור הסמפורים ()FIFO
האם הקריאה ל resched-הכרחית כפי שהיתה הכרחית
ב?wait-
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה screate.c – screate
לא ניתן ליצור
סמפור עם ערך
התחלתי שלילי .מה
המשמעות של ערך
שלילי?
10
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה screate
11
ביצוע signalלא מופרע באמצע ע"י מערכת ההפעלה.
הגנה באמצעות .disable/restoreאולם החלפת הקשר
היא אפשרית גם באמצע עקב reschedיזום
לא ניתן לבצע signalעל סמפור שלא נוצר ,או שכבר
שוחרר
ההוצאה מראש תור הסמפורים ()FIFO
האם הקריאה ל resched-הכרחית כפי שהיתה הכרחית
ב?wait-
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה – screateהמשך
בעת אתחול
המערכת הוצב
קבוע SFREEלכל
רשומות הסמפורים
12
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה sdelete
13
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה sdelete
אם ,בעת מחיקת הסמפור ,קיימים תהליכים המחכים לו ,משחררים
את כל התהליכים
בסוף לולאת whileמבצעים .reschedהאם מותר גם בתוך
הלולאה?
לשים לב :מחיקת סמפור כאשר יש תהליכים המחקים בתור היא
פעולה מסוכנת ולא טבעית (הרי יש סיבה שבגללה הם מחכים
לסמפור)...
ישנן מערכות הפעלה בהן לא ניתן לשחרר סמפור שתורו לא ריק
14
מערכות הפעלה -תרגול 2
אפריל 15
signaln.c
)( readyמרכזת את כל
הטיפול בתור
התהליכים המוכנים
15
מערכות הפעלה -תרגול 2
אפריל 15
sreset.c
מה ההבדל בין קריאה
ל sreset-לבין שתי
קריאות רצופות ל-
sdeleteו?screate-
16
מערכות הפעלה -תרגול 2
אפריל 15
העברת הודעות -יישום
משלוח הודעות – לא חוסם
קבלת הודעות – חוסמת או לא חוסמת
בקבלה חוסמת ,אם לא ממתינה הודעה ,מחכים
השולח משאיר את ההודעה בטבלת התהליכים ,בשדות
המיועדים לכך
כאשר שולח מבקש לשלוח הודעה לתהליך שעדיין לא
קרא הודעה קודמת ,ההודעה החדשה אינה נשלחת
אם השולח מזהה שהתהליך המחכה נמצא במצב מחכה
להודעה ,השולח מחזיר את התהליך המקבל לריצה
* תהליך המקבל הודעה אינו יודע מי השולח
17
מערכות הפעלה -תרגול 2
אפריל 15
הודעות בXINU-
XINUמוגבלת מאוד באמצעי העברת ההודעות
שלה.
סוגי העברה:
משלוח לא חוסם ( sendלמיניהם)
קבלה חוסמת ולא חוסמת ()receiveclr, receive
שליחת ההודעות לתהליך מסויים
18
מערכות הפעלה -תרגול 2
אפריל 15
הודעות בXINU-
באמצעות העברת ההודעות ב XINU-ניתן:
להעביר מסרים
לתאם בין תהליכים (בנוסף לסמפורים)
הגבלות:
הודעה באורך של שני בתים בלבד ()integer
כשמגיעים מספר מסרים ,רק הראשון מתקבל והשאר
אובדים
19
מערכות הפעלה -תרגול 2
אפריל 15
העברת הודעות – מבנה נתונים
מצב התהליך – ,PRRECVתהליך מחכה נמצא
במצב ( PRRECVמיוחד להמתנה להודעות)
שדות pmsgו phasmsg-בטבלת התהליכים
ההודעה הנשלחת לתהליך מוכנסת לשדה pmsg
ברשומת התהליך
השדה phasmsgמסמן אם יש הודעה ממתינה
20
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה send.c – send
21
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מערכת הפעלה – send.c
send מתבצעת בצורה רצופה מבלי שתופרע ע"י
מערכת ההפעלה
אולם ,החלפת ההקשר יכולה לקרות ע"י resched
יזום
בדיקות תקינות כוללות בדיקה שאין כבר הודעה
המחכה עבור התהליך המקבל
אם התהליך מחכה מעירים אותו ומבצעים
resched
22
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה receive.c – receive
23
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה receive.c –receive
receive מתבצעת בצורה רצופה מבלי שתופרע
ע"י מערכת ההפעלה
אולם ,החלפת ההקשר יכולה לקרות ע"י resched
יזום
אם אין הודעה התהליך עובר למצב PRRECV
ויוצא מהמעבד אחרי resched
האם הוא נמצא בתור כלשהו? איך יחזור לפעולה?
למה שומרים הודעה במשתנה לוקלי ?msg
24
מערכות הפעלה -תרגול 2
אפריל 15
קריאת מ"ה receiveclr.c – receiveclr
25
מערכות הפעלה -תרגול 2
אפריל 15
מניעה הדדית
המטרה היא למנוע מצב שבוא שני תהליכים יגשו
לאותו משאב בו זמנית
התסריט הלא רצוי הוא שתהליך אחד יתחיל לבצע
פעולה על המשאב ואז יופסק ע"י פסיקה מבלי
שיספיק לבצע את השינוי
במקרה כזה ,תהליך שני יקבל את המשאב במצב
לא תקין
26
מערכות הפעלה -תרגול 2
אפריל 15
פתרון למניעה הדדית ברמת המ"ה
ניתן לכבות את מנגנון הפסיקות (כיבוי )IF
במערכות המודרניות משתמשים בשיטה זו:
בקוד הפנימי של מערכת הפעלה
תוכניות קלט/פלט (כגון קריאה של USBאו רשת)
הפתרון חסום ברמת האפליקציה
27
מערכות הפעלה -תרגול 2
אפריל 15
מניעה הדדית באמצעות mutex
ראינו מימוש אפשרי של מניעה הדדית באמצעות
הסמפורים
בדרך כלל הדבר נעשה ע"י מימוש מנגנון נעילות
הקרוי mutex
מנגנון הנעילה מזוהה עם משאב משותף שעבורו
רוצים למנוע גישה בו-זמנית
מנגנון הנעילות לא מבטיח שתהליך שנכנס לקטע
קריטי לא ייעצר עד שיצא ממנו .הוא מבטיח
שתהליכים אחרים לא יכנסו לקטע קריטי נעול
28
מערכות הפעלה -תרגול 2
אפריל 15
מניעה הדדית באמצעות mutex
אם קטע קריטי נעול על ידי תהליך מסויים כל היתר
לא יצליחו לעבור מנעול ויעצרו בכניסה לקטע קריטי
המנגנון לא מסוגל לכפות את עצמו על אף תהליך
התהליך חייב להיות מתוכנת לגשת לקטע קריטי
דרך מנגנון הנעילות
29
מערכות הפעלה -תרגול 2
אפריל 15
הפעלת mutex
שני מצבים – "פתוח" ו"-נעול"
התהליך שנכנס לקטע קריטי "נועל" ( )lockאת
,mutexמבצע קטע קריטי ו"משחרר"
)(unlockאת mutexביציאה
אם תהליך מנסה לנעול מנגנון נעילות נעול ,הוא
נעצר ומצטרף לתור הממתינים למנגנון הנעילות
30
מערכות הפעלה -תרגול 2
אפריל 15
mutex קריאות
:נעילה
mutex_lock(&global_variable);
:שחרור
mutex_unlock(&global_variable);
:דוגמה
MUTEX_VAR mtx = MUTEX_VAR_INITIALIZER;
mutex_lock(&mtx);
critical_variable++;
mutex_unlock(&mtx);
15 אפריל
2 תרגול- מערכות הפעלה
31
מימוש מנגנון הנעילות
ניתן לממש את מנגנון הנעילות בעזרת סמפור
ניתן להשתמש בסמפור יחיד שהערך ההתחלתי
של המונה שלו הוא .1
נקצה עבור כל מנגנון הנעילות רשומה המכילה:
סטטוס של מנגנון – סגור או פתוח
מספר הסמפור שהוקצה
שדה המציין את הבעלים הזמניים של מנגנון
32
מערכות הפעלה -תרגול 2
אפריל 15
הגדרת הרשומה – mutex.h
33
מערכות הפעלה -תרגול 2
אפריל 15
SYSCALL mutex_lock(MUTEX_REC_PTR *mutex_var)
{
int nsem;
int ps, ans;
mutex.c
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;
}
15 אפריל
2 תרגול- מערכות הפעלה
34
mutex_lock
בנעילה ראשונה יוצרים רשומת mutex
מקצים סמפור עבור המנגנון ונשמור את ה sid-שלו
ברשומה
מחכים בתור לכניסה למנגנון הנעילה
מעדכנים את הפרטים של הבעלים הנוכחיים של
mutex
משחזרים פסיקות .בפועל זה קורה פעמיים –
בתוך screateוגם בתוך הקריאה עצמה
35
מערכות הפעלה -תרגול 2
אפריל 15
SYSCALL mutex_unlock(MUTEX_REC_PTR *mutex_var)
{
int ps;
mutex.c
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 */
15 אפריל
2 תרגול- מערכות הפעלה
36
mutex_unlock
אם התור הוא ריק הרשומה משתחררת והסמפור
נמחק
אם יש תהליכים המחכים בתור נקראת signalכדי
לשחרר את התהליך הבא
התהליך משחרר נעילה ויוצא מקטע קריטי
התהליך המשוחרר נמצא באמצע פעולת .lockהוא
רושם את עצמו כבעלים החדשים של mutex
ומבצע קטע קריטי
37
מערכות הפעלה -תרגול 2
אפריל 15
דוגמה :בנק
קיימים 2חשבונות בנק
הכספים עוברים מחשבון לחשבון
אל המשתנים הגלובליים ניגשים שני תהליכים:
תהליך ראשון מעביר סכומים מחשבון לחשבון
תהליך שני מדפיס סה"כ כסף בשני החשבונות
הסה"כ צריך להיות קבוע .האם זה קורה באמת?
38
מערכות הפעלה -תרגול 2
אפריל 15
testmu1.c – 1 ממוש
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;
}
}
15 אפריל
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 תרגול- מערכות הפעלה
39
testmu1.c
הסכום הלא מתאים מודפס בכל מקרה גם פעם ב-
30000מקרים אם הוא מתאים
המימוש לא מגן על המשאב המשותף עם מנגנון
הנעילות
נראה גיוון מספרים בפלט
40
מערכות הפעלה -תרגול 2
אפריל 15
פלט- 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
15 אפריל
הפלט מכיל מספרים
שונים
2 תרגול- מערכות הפעלה
41
testmu2.c – 2 ממוש
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);
}
}
15 אפריל
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 תרגול- מערכות הפעלה
42