מערכות הפעלה

Download Report

Transcript מערכות הפעלה

‫מערכות הפעלה‬
‫תרגול ‪ – 3‬תהליכים‪ ,‬תאום תהליכים‬
‫מה בתכנית?‬
‫‪ ‬תיאום תהליכים – המשך‬
‫‪ ‬עדיפויות‬
‫‪ ‬תהליכים ב‪UNIX-‬‬
‫‪2‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫תאום תהליכים‬
‫‪3‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫תאום תהליכים – למה לתאם?‬
‫‪ ‬סינכרון פעולות בין תהליכים‬
‫‪ ‬מניעה הדדית – מנגנונים המבטיחים שרק‬
‫תהליך אחד מבצע פעילות מסוימת‬
‫‪‬הגנה על משאב משותף‬
‫‪ ‬דוגמה‪ :‬מדפסת‪ ,CD ,‬זכרון‪ ,‬מסד נתונים‬
‫‪‬הגנה על קוד משתמש משותף (קטע קריטי)‬
‫‪4‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫קטע קריטי (‪)critical section‬‬
‫‪‬‬
‫‪‬‬
‫קטע קריטי הוא קטע קוד שמבוצע רק על ידי תהליך אחד בו זמנית‬
‫מבנה‪:‬‬
‫‪shared section‬‬
‫‪trying/entry section‬‬
‫‪critical section‬‬
‫‪exit section‬‬
‫‪‬‬
‫‪5‬‬
‫דוגמה – בנק הפועלים מהתרגול הקודם‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫קטע קריטי (‪)critical section‬‬
‫תכונות רצויות‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪6‬‬
‫אין הרעבה –> אין קיפאון‬
‫אבל ההיפך אינו נכון‬
‫רק תהליך אחד נמצא בקטע קריטי (מניעה הדדית –‬
‫‪)mutual exclusion‬‬
‫אם יש בקשות לקטע הקריטי אזי לפחות תהליך אחד נכנס‬
‫לקטע הקריטי (אין קיפאון ‪)no deadlock‬‬
‫הוגנות )‪ -(fairness‬אם תהליך מבקש להכנס לקטע‬
‫הקריטי אזי יצליח בסופו של דבר (אין הרעבה ‪no‬‬
‫‪)starvation‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫קטע קריטי (‪)critical section‬‬
‫‪‬‬
‫‪‬‬
‫אטומיות‪ -‬פעולה (סדרת פקודות) של תהליך אחד‬
‫מבוצעת ללא חפיפה עם פעולה (סדרת פקודות) של‬
‫תהליך אחר‬
‫מניעה הדדית (ביצוע סדרת הפקודות בתוך קטע קריטי)‬
‫הינה דרך להבטיח אטומיות באמצעות תוכנה‬
‫אבל לא הדרך היחידה‪...‬‬
‫‪7‬‬
‫אפשר גם בחומרה‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
)critical section( ‫קטע קריטי‬
semaphore lock;
...
read_security_code(screen);
amount = read_amount(screen);
wait(lock) // acquire lock
balance = get_balance(account);
balance -= amount;
// 50K-20K
put_balance(account, balance);
return balance;
‫קטע קריטי‬
// = 30K
signal(lock) // release lock
show_balance(screen, balance);
...
3 ‫ תרגול‬- ‫מערכות הפעלה‬
8
‫דוגמאות לבעיות בתחום תאום תהליכים‬
‫‪ ‬כותבים‪/‬קוראים‬
‫‪ ‬המספרה והספר הישן‬
‫‪ ‬הפילוסופים הסועדים‬
‫‪9‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫בעיית כותבים‪/‬קוראים‬
‫‪ ‬מוטיבציה‪ :‬גישה למסד הנתונים‬
‫‪ ‬שני סוגי תהליכים – קוראים‬
‫וכותבים‬
‫‪ ‬כמה קוראים ביחד יכולים לגשת‬
‫למסד נתונים בו זמנית‬
‫‪ ‬כותב אחד בלבד יכול לגשת בו‬
‫זמנית‬
‫‪10‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫קוראים‬
‫כותב‬
‫קוראים‬/‫בעיית כותבים‬
int readers = 0 // # of reading processes
semaphore rc_access = 1; // controls access to rc
semaphore db = 1; // controls database access
void writer(void){
while(TRUE){
wait(db);
write_data_base()
signal(db)
}
void reader(void){
while(TRUE){
wait(rc_access);
readers = readers + 1;
if(readers == 1)
wait(db);
signal(rc_access);
read_data_base();
wait(rc_access);
readers = readers - 1;
if(readers == 0)
signal(db);
signal(rc_access); }
‫מי ירוץ יותר – קוראים או‬
?‫כותבים‬
}
3 ‫ תרגול‬- ‫מערכות הפעלה‬
11
‫בעיית כותבים‪/‬קוראים‬
‫‪ ‬אף קורא לא מחכה אם הגישה למסד נתונים היא‬
‫לא בידי הכותב (סמפור ‪)db‬‬
‫‪ ‬אם קוראים חדשים מגיעים כל הזמן ומחזיקים‬
‫בסמפור ‪ – db‬הרעבה של כותב‬
‫‪ ‬עדיף לדרוש תנאי‪ :‬אף כותב לא מחכה עם הוא‬
‫"מוכן" – אם כותב מחכה אף קורא נוסף לא יכול‬
‫להתחיל לקרא‬
‫‪12‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫המספרה‪ ,‬או בעיית הספר הישן‬
‫קיים ספר אחד ו‪ N-‬כסאות ללקוחות‬
‫שמחכים‬
‫אם אין לקוחות אז הספר יושב בכיסא‬
‫וישן (כמו בתמונה)‬
‫כשמגיע לקוח חדש והספר ישן הוא יעיר‬
‫את הספר‬
‫כשהלקוח מגיע והספר עסוק הוא ישב‬
‫על אחד הכסאות‪ ,‬אם קיים כיסא פנוי‪,‬‬
‫אחרת (הכל מלא) הוא יעזוב‬
‫‪13‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫בעיות שעלולות להתעורר‪:‬‬
‫‪ ‬לקוח מגיע‪ ,‬רואה שהספר עסוק‪ ,‬מתיישב ומחכה‪.‬‬
‫כשהו בדרכו להתיישב‪ ,‬הספר מסיים את‬
‫התספורת והולך לבדוק את חדר ההמתנה‪ .‬מאחר‬
‫ואין שם אף אחד הוא חוזר לישון‪.‬‬
‫‪ ‬שני לקוחות מגיעים באותו זמן‪ ,‬רואים שהספר‬
‫עסוק‪ ,‬רואים שיש כיסא אחד פנוי ומנסים‬
‫להתיישב‪ .‬שנייהם ינסו להתיישב באותו כיסא‪.‬‬
‫‪14‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫ או בעיית הספר הישן‬,‫המספרה‬
int customers = 0;
access = semaphore(1);
customer = semaphore(0);
barber = semaphore(0);
void barber (void) {
while(TRUE){
wait(customer);
signal(barber);
cutHair();
}
}
void customer (void) {
while(TRUE){
wait(access);
if (customers>=CHAIRS) {
signal(access);
leave_shop();
}
customers +=1;
signal(access);
signal(customer);
wait(barber);
getHairCut();
wait(access);
customers -=1;
signal(access);
}
3 ‫תרגול‬
} - ‫מערכות הפעלה‬
15
‫הפילוסופים הסועדים‬
‫‪ ‬חמישה פילוסופים מעבירים‬
‫את זמנם באכילה ומחשבה‬
‫‪ ‬כל פילוסוף צריך ‪ 2‬מזלגות‬
‫כדי לאכול‬
‫‪ ‬פילוסוף לא יכול לקחת יותר‬
‫ממזלג אחד בו זמנית‬
‫* פילוסוף – תהליך‪ ,‬מזלג ‪-‬‬
‫משאב‬
‫‪16‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫הפילוסופים הסועדים‬
‫האם הכל בסדר?‬
‫{ )(‪void philosopher‬‬
‫{ )‪while(1‬‬
‫אם כל פילוסוף יבחר במזלג שמאלי‬
‫;)(‪think‬‬
‫באותו זמן אף אחד לא הולך‬
‫;)(‪get_left_fork‬‬
‫לאכול‪ ...‬אף פעם! סכנה של‬
‫;)(‪get_right_fork‬‬
‫‪!Deadlock‬‬
‫;)(‪eat‬‬
‫;)(‪put_left_fork‬‬
‫;)(‪put_right_fork‬‬
‫}‬
‫}‬
‫‪17‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫הפילוסופים – מה עושים?‬
‫קח מזלג מצד שמאל‪ .‬אם המזלג מצד ימין פנוי קח‬
‫אותו גם‪ .‬אם לא‪ ,‬תחזיר מזלג שלקחת‪ ,‬חכה ונסה שוב‪.‬‬
‫‪ 2‬בעיות‪:‬‬
‫‪ ‬אם כל הפילוסופים מחכים אותו פרק זמן – חוזרים‬
‫לאותו מצב כמו קודם‬
‫‪ ‬אם הזמנים הם שונים עדיין ייתכן ויהיה פילוסוף חסר‬
‫מזל שיישאר רעב (במובן המילולי והטכני)‬
‫‪18‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫אז מה בכל זאת?‬
‫‪‬‬
‫‪19‬‬
‫רעיון‪ :‬להשתמש בגורם נוסף שממנו‬
‫יבקשו משאבים‪ ,‬והוא לא ירשה לקחת‬
‫מזלג חמישי‪.‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫הפילוסופים הסועדים‬
‫ולבעיה האמיתית‪...‬‬
‫‪20‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫עדיפויות‬
‫תהליכים‬
‫‪21‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫עדיפויות תהליכים‬
‫‪ ‬עדיפות משפיעה על תדירות ההכנסה של תהליך‬
‫לריצה פעילה ועל מיקומו בתור התהליכים המחכים‬
‫למעבד‬
‫‪ ‬הגדרת עדיפות גבוהה לתהליך מבטיחה שירוץ‬
‫ללא הפרעות מצידם של תהליכים עם עדיפות‬
‫נמוכה (למשל‪ ,‬אנטיוירוס)‬
‫‪ ‬במ"ה מודרניות עדיפויות יכולות להשתנות בזמן‬
‫ריצה של התהליך כתלות בהתנהגותו‬
‫‪22‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫תהליכים עם עדיפויות זהות‬
‫תור תהליכים‬
‫‪B‬‬
‫‪2‬‬
‫‪0‬‬
‫‪1‬‬
‫‪2‬‬
‫‪B‬‬
‫‪0‬‬
‫‪2‬‬
‫‪3‬‬
‫‪1‬‬
‫‪0‬‬
‫‪1‬‬
‫תהליך במעבד‬
‫‪23‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪A‬‬
‫‪0‬‬
‫‪2‬‬
‫‪2‬‬
‫‪3‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪A‬‬
‫‪0‬‬
‫‪2‬‬
‫‪2‬‬
‫‪1‬‬
‫‪A‬‬
‫‪0‬‬
‫‪2‬‬
‫‪2‬‬
‫‪1‬‬
‫‪1‬‬
‫‪3‬‬
‫‪1‬‬
‫‪2‬‬
‫‪A‬‬
‫‪0‬‬
‫‪2‬‬
‫‪2‬‬
‫‪3‬‬
‫‪1‬‬
‫‪2‬‬
‫‪A‬‬
‫ריצת תהליכים ב‪CPU-‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫‪2‬‬
‫זמן‬
‫תהליכים עם עדיפויות שונות‬
‫‪ – pid1‬עדיפות ‪ - pid2 ,20‬עדיפות ‪ – pid3 ,20‬עדיפות ‪21‬‬
‫ריצת תהליכים ב‪CPU-‬‬
‫תור תהליכים‬
‫‪0‬‬
‫‪2‬‬
‫‪2‬‬
‫‪1‬‬
‫‪0‬‬
‫‪2‬‬
‫‪2‬‬
‫‪1‬‬
‫‪0‬‬
‫‪1‬‬
‫‪2‬‬
‫‪0‬‬
‫‪1‬‬
‫‪2‬‬
‫‪B‬‬
‫‪0‬‬
‫‪2‬‬
‫‪2‬‬
‫‪1‬‬
‫‪A‬‬
‫‪0‬‬
‫‪1‬‬
‫‪1‬‬
‫‪2‬‬
‫‪A‬‬
‫‪A‬‬
‫‪A‬‬
‫‪3‬‬
‫‪1‬‬
‫‪2‬‬
‫זמן‬
‫‪24‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
ex8.c ‫יצירת תהליכים עם עדיפויות שונות‬
int count1 = 0, count2 = 0, count3 = 0;
xmain()
{
int Inc(), Pr();
count<i>-‫ ל‬1 ‫ מוסיף‬- Inc<i>
count1, count2, count3 ‫ – מדפיס מונים‬Pr
resume( create(Inc, INITSTK, INITPRIO, "proc 1", 1, &count1) );
resume( create(Inc, INITSTK, INITPRIO, "proc 2", 1, &count2) );
resume( create(Inc, INITSTK, INITPRIO - 1, "proc 3", 1, &count3) );
resume( create(Pr, INITSTK, INITPRIO + 1, "proc 4", 0) );
}
Inc(int ptr)
{
int *ptr1;
ptr1 = (int *)ptr;
while (1)
(*ptr1)++;
}
‫האם ניתן‬
Pr()
‫למחוק‬
{
while(1)
?sleep()
{
sleep(3);
printf("count1 = %d, count2 = %d, count3 = %d\n",
count1, count2, count3);
}
}
3 ‫ תרגול‬- ‫מערכות הפעלה‬
25
‫יצירת תהליכים עם עדיפויות שונות ‪ex8.c‬‬
‫למה המספרים מודפסים‬
‫עם "‪?"-‬‬
‫‪26‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
ex8.c ‫יצירת תהליכים עם עדיפויות שונות‬
unsigned long int count1 = 0, count2 = 0, count3 = 0;
xmain()
{
int Inc(), Pr();
resume( create(Inc, INITSTK, INITPRIO, "proc 1", 1, &count1) );
resume( create(Inc, INITSTK, INITPRIO, "proc 2", 1, &count2) );
resume( create(Inc, INITSTK, INITPRIO - 1, "proc 3", 1, &count3) );
resume( create(Pr, INITSTK, INITPRIO + 1, "proc 4", 0) );
}
Inc(int ptr)
{
unsigned long int *ptr1;
ptr1 = (unsigned long int *)ptr;
while (1)
(*ptr1)++;
}
Pr()
{
while(1)
{
char str[80];
sleep(3);
sprintf("count1 = %lu, count2 = %lu,
count3 = %lu \n", count1, count2, count3);
printf(str);
}
}
3 ‫ תרגול‬- ‫מערכות הפעלה‬
27
‫יצירת תהליכים עם עדיפויות שונות ‪ex8.c‬‬
‫‪28‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫תהליכים בסביבת ‪LINUX/UNIX‬‬
‫‪29‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫תהליכים בסביבת ‪LINUX/UNIX‬‬
‫כל תהליך נוצר כעותק של תהליך קיים‬
‫‪ ‬התהליך המקורי נקרא תהליך אב (או הורה)‬
‫‪ ‬התהליך החדש נקרא תהליך בן‬
‫‪ ‬תהליך הבן נוצר בעקבות ביצוע קריאת מערכת‬
‫הפעלה )(‪ fork‬על‪-‬ידי תהליך האב‬
‫‪ ‬תהליך אב יכול ליצור יותר מתהליך בן אחד‬
‫‪30‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫יצירת תהליך‬
‫‪‬‬
‫קריאת המערכת )(‪fork‬‬
‫‪ ‬תחביר‪:‬‬
‫;)(‪pid_t fork‬‬
‫‪ ‬פעולה‪ :‬מעתיקה את תהליך האב לתהליך הבן וחוזרת בשני‬
‫התהליכים‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫קוד זהה (ומיקום בקוד)‬
‫זיכרון זהה (משתנים וערכיהם‪ ,‬חוצצים)‬
‫סביבה זהה (קבצים פתוחים‪ ,file descriptors ,‬ספרית עבודה נוכחית)‬
‫‪ ‬פרמטרים‪ :‬אין‬
‫‪ ‬ערך מוחזר‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪31‬‬
‫במקרה של כישלון‪ -1 :‬לאב (אין בן)‬
‫במקרה של הצלחה‪ :‬לבן מוחזר ‪ 0‬ולאב מוחזר ה‪ pid-‬של הבן‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫יצירת תהליך‬
‫‪‬‬
‫לאחר פעולת )(‪ fork‬מוצלחת‪ ,‬אמנם יש לאב ולבן את אותם‬
‫משתנים בזיכרון‪ ,‬אך בעותקים נפרדים‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫כלומר‪ ,‬שינוי ערכי המשתנים אצל האב לא ייראה אצל הבן‪ ,‬וההיפך‬
‫כמו כן‪ ,‬תהליך הבן הוא תהליך נפרד מתהליך האב לכל דבר‪.‬‬
‫בפרט‪ ,‬יש לו ‪ pid‬משלו‬
‫מה מדפיס הקוד הבא?‬
‫{ )(‪main‬‬
‫;)(‪fork‬‬
‫;)”‪printf(“hello‬‬
‫}‬
‫‪32‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
?‫איך מבדילים בן אב לבן‬
:)‫ הצליחה‬fork()-‫תשובות אפשריות (בהנחה ש‬

‫ שני תהליכים כותבים פלט בצורה לא מתואמת‬:‫הסיבה‬
:fork()-‫מבנה תכנית אופייני המשתמש ב‬

hellohello
hheellollo

status = fork();
if (status < 0)
// fork() failed – handle error (e.g. message & exit)
if (status == 0)
// son process – do son code
else
// father process – do father code
3 ‫ תרגול‬- ‫מערכות הפעלה‬
33
‫הרצת תכנית אחרת‬
‫‪‬‬
‫קריאת המערכת )(‪execv‬‬
‫‪ ‬תחביר‪:‬‬
‫;)][‪int execv(const char *filename, char *const argv‬‬
‫‪ ‬פעולה‪ :‬טוענת תכנית חדשה לביצוע על‪-‬ידי התהליך הקורא‬
‫‪ ‬פרמטרים‪:‬‬
‫‪‬‬
‫‪ – filename‬מסלול אל הקובץ המכיל את התכנית לטעינה‬
‫‪ ‬ערך מוחזר‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪34‬‬
‫במקרה של כישלון‪-1 :‬‬
‫במקרה של הצלחה‪ :‬הקריאה אינה חוזרת‪ .‬איזורי הזיכרון של התהליך‬
‫מאותחלים לתכנית החדשה שמתחילה להתבצע מההתחלה‪.‬‬
‫‪ – argv‬מערך מצביעים למחרוזות המכיל את הפרמטרים עבור התכנית‪.‬‬
‫האיבר הראשון מקיים ‪ argv[0] == filename‬או רק מכיל את שם קובץ‬
‫התכנית‪ .‬האיבר שאחרי הפרמטר האחרון מכיל ‪NULL‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫הרצת תכנית אחרת‬
‫‪‬‬
‫מה ידפיס הקוד הבא?‬
‫{ )(‪main‬‬
‫;}‪char *argv[] = {“date”, NULL‬‬
‫;)‪execv(“/bin/date”, argv‬‬
‫;)”‪printf(“hello‬‬
‫}‬
‫‪‬‬
‫התשובה‪:‬‬
‫‪ ‬אם )(‪ execv‬מצליחה‪ :‬את התאריך והשעה‬
‫‪ ‬אם )(‪ execv‬נכשלת‪hello :‬‬
‫‪35‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫דוגמה לשילוב‬
:execv() ‫ עם‬fork() ‫דוגמה אופיינית לשילוב‬

pid = fork();
if (pid < 0) {
handle fork() error
}
if (pid > 0)
// do father code
else
execv(“son_prog”, argv_son);
3 ‫ תרגול‬- ‫מערכות הפעלה‬
36
‫עצירת תהליך‬
‫‪‬‬
‫קריאת המערכת )(‪exit‬‬
‫‪ ‬תחביר‪:‬‬
‫;)‪void exit(int status‬‬
‫‪ ‬פעולה‪ :‬מסיימת את ביצוע התהליך הקורא ומשחררת את כל‬
‫המשאבים שברשותו‪ .‬התהליך עובר למצב ‪ zombie‬עד‬
‫שתהליך האב יבקש לבדוק את סיומו ואז יפונה לחלוטין‬
‫‪ ‬פרמטרים‪:‬‬
‫‪‬‬
‫‪ – status‬ערך סיום המוחזר לאב אם יבדוק את סיום התהליך‬
‫‪ ‬ערך מוחזר‪ :‬הקריאה אינה חוזרת‬
‫‪37‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫תהליכי ‪Zombie‬‬
‫‪ ‬כדי לאפשר לאב לקבל מידע על סיום הבן‪ ,‬לאחר‬
‫שתהליך מסיים את פעולתו הוא עובר למצב מיוחד‬
‫– ‪ – zombie‬שבו התהליך קיים כרשומת נתונים‬
‫בלבד ללא שום ביצוע משימה‬
‫‪ ‬הרשומה נמחקת לאחר שהאב קיבל את המידע על‬
‫סיום הבן‬
‫‪ ‬מה קורה לתהליך שהופך ל"יתום" (‪)orphan‬‬
‫לאחר שאביו כבר סיים?‬
‫‪ ‬התהליך הופך להיות בן של תהליך איתחול במערכת‬
‫ההפעלה‬
‫‪38‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬
‫בשיעור הבא‪...‬‬
‫‪ ‬מימוש תהליכים ב‪XINU-‬‬
‫‪39‬‬
‫מערכות הפעלה ‪ -‬תרגול ‪3‬‬