370 likes | 728 Views
מערכות הפעלה. תרגול 4 – ניהול תהליכים, מבני נתונים למימוש תהליכים. מה בתכנית?. ניהול תהליכים מימוש תהליכים ב- XINU טבלת תהליכים מימוש תורי תהליכים תרגילים. ניהול תהליכים. המעבד מריץ את כל התהליכים אך בכל רגע נתון הוא מריץ תהליך בודד
E N D
מערכות הפעלה תרגול 4 – ניהול תהליכים, מבני נתונים למימוש תהליכים
מה בתכנית? • ניהול תהליכים • מימוש תהליכים ב-XINU • טבלת תהליכים • מימוש תורי תהליכים • תרגילים מערכות הפעלה - תרגול 2
ניהול תהליכים • המעבד מריץ את כל התהליכים אך בכל רגע נתון הוא מריץ תהליך בודד • התהליך המורץ במעבד נקרא תהליך נוכחי (current process) • תהליכים אחרים מחכים לביצוע במעבד, או מחכים לקבלת משאב אחר מערכות הפעלה - תרגול 2
ניהול תהליכים • מערכת ההפעלה אחראית על כך שבכל רגע ורגע יהיה תהליך אחד מוגדר כתהליך הנוכחי • במידה והתהליך מוותר על מעמדו כתהליך הנוכחי או שמערכת ההפעלה מחליטה להחליפו, עליה לבחור תהליך אחר שיחליף אותו מערכות הפעלה - תרגול 2
ניהול תהליכים • האלגוריתם המחליט האם להחליף את התהליך הנוכחי ומי התהליך שיחליפו נקרא זמן (Scheduler) • בזמן החלפת התהליך הנוכחי יש לשמור את ההקשר שלו (context) (הכולל את ערכי הרגיסטרים שונים) כדי שניתן יהיה לשחזר אותו בזמן החזרתו לביצוע (החלפת הקשר, Context Switching) מערכות הפעלה - תרגול 2
מדיניות הזימון • התהליך הנוכחי נבחר בין תהליכים המחכים למעבד • קיימות כמה שיטות לבחירת התהליך הנוכחי: • מדיניות FIFO • בחירה סדרתית (Round-Robin) • בחירה לפי עדיפות • בחירה לפי זמן ריצה מערכות הפעלה - תרגול 2
First Come First Serve (or FIFO) • במקור, תהליך אחד משתמש במעבד עד לסיומו • כיום, תהליך משתמש במעבד עד שנחסם בהמתנה למאורע כלשהו • מדיניות ללא הפקעה (non-preemptive) תהליכים קצרים "נתקעים" אחרי תהליכים ארוכים => תהליכים קצרים נמצאים הרבה זמן בתור המוכנים, יחסית לזמן החישוב שהם צורכים מערכות הפעלה - תרגול 2
Round-Robin • כל תהליך מקבל את המעבד לפרק זמן קצוב, ולאחריו הוא מוחלף באחר אף אם לא סיים. ההחלפה נעשית לפי סדר קבוע (Round-Robin) • חלוקת זמן בין התהליכים השונים הוגנת • דוגמה: נוכחי מערכות הפעלה - תרגול 2
מדיניות הזימון • לפי עדיפות: לכל תהליך משוייך מספר עדיפות. התהליך בעל עדיפות גבוהה ביותר המחכה למעבד הופך לתהליך הנוכחי • סדר העדיפויות: 1 6 8 9 10 13 מערכות הפעלה - תרגול 2
מדיניות הזימון לפי עדיפות • התהליך הנוכחי יאבד את המעבד רק אם תהליך בעל עדיפות גבוהה יותר ידרוש אותו, או שהנוכחי יוותר עליו • אם תהליך בעל עדיפות גבוהה יותר לא ישחרר את המעבד, תהליכים בעלי עדיפות נמוכה יותר לא יתבצעו • קיימות מ"ה בהן תהליך שמתבצע מאבד את עדיפותו עם הזמן, ותהליך שמחכה משפר את עדיפותו כדי לאפשר "צדק" גדול יותר בחלוקת משאב המעבד מערכות הפעלה - תרגול 2
מדיניות הזימון – היישום ב-XINU • XINU משתמשת בשיטת העדיפויות כאשר בין התהליכים באותה עדיפות מתבצע Round-Robin • העדיפות של תהליך נקבעת בזמן יצירתו, אך ניתנת לשינוי בכל עת. מערכות הפעלה - תרגול 2
תהליך - דיאגרמת מצבים send receive RECEIVING wait signal WAITING sleep wake up SLEEPING resched resched CURRENT READY SUSPENDED suspend suspend resume Create מערכות הפעלה - תרגול 2
טבלת תהליכים • קיימת טבלת תהליכים, המיוצגת כוקטור של רשומות, בה כל רשומה מייצגת הקשר של תהליך, ולכל תהליך מוקצת רשומה • רשומה מכילה את המידע על מצב התהליך ואת כל המידע על הקשר התהליך הדרוש להפעלתו • קיימים מספר משתנים המייצגים את מצב התהליך או שמציינים שתהליך מחכה למשאב כלשהו מערכות הפעלה - תרגול 2
טבלת תהליכים • האינדקס בטבלת התהליכים משמש כמזהה של התהליך (pid – process identifier) • המזהה של התהליך הנוכחי שמור במשתנה נפרד המאפשר התיחסות לתהליך הנוכחי מקוד מ"ה • התהליכים המחכים למעבד שמורים בתור דו-כווני על פי עדיפותם. תור זה נקרא ready queue ומבוצע על ידי rdyhead, rdytail מערכות הפעלה - תרגול 2
טבלת תהליכיםproc.h - #define NULLPROC 0 /* id of the null process; it */ /* is always eligible to run */ extern struct pentry proctab[]; extern int numproc; /* currently active processes */ extern int nextproc; /* search point for free slot */ extern int currpid; /* currently executing process */ מערכות הפעלה - תרגול 2
טבלת תהליכיםproc.h - /* process table entry */ struct pentry { char pstate; /* process state: PRCURR, etc. */ int pprio; /* process priority */ int psem; /* semaphore if process waiting */ int pmsg; /* message sent to this process */ int phasmsg; /* nonzero iff pmsg is valid */ char *pregs; /* saved environment */ char *pbase; /* base of run time stack */ word plen; /* stack length in bytes */ char pname[PNMLEN+1]; /* process name */ int pargs; /* initial number of arguments */ int (*paddr)(); /* initial code address */ }; מערכות הפעלה - תרגול 2
טבלת תהליכיםproc.h - #defineNPROC 30 /* process state constants */ #definePRCURR '\01' // process is currently running #definePRFREE '\02' // process slot is free #definePRREADY '\03' // process is on ready queue #definePRRECV '\04' // process waiting for message #definePRSLEEP '\05' // process is sleeping #definePRSUSP '\06' // process is suspended #definePRWAIT '\07' // process is on semaphore queue מערכות הפעלה - תרגול 2
תהליך ה-NULL מה עושה מ"ה כאשר אין תהליך הדורש מעבד? • אחת הדרכים האפשריות היא לתת לזמן לבצע לולאה ולחכות עד שתהליך כלשהו יהיה מוכן לחזור לביצוע אך לשם כך שקוד הזמן יהיה מורכב יותר • דרך מועדפת הינה ליצור תהליך שתמיד יהיה מוכן לחישוב מערכות הפעלה - תרגול 2
תהליך ה-NULL • תהליך זה נקרא NULL process ובנוי כלולאה אינסופית מהצורה While (TRUE) /* Do nothing */; • תהליך ה-NULL יקבל את העדיפות המזערית האפשרית ולכן יהפך לנוכחי רק כאשר אין אף תהליך אחר שדורש את המעבד • המזהה של תהליך זה הוא 0 מערכות הפעלה - תרגול 2
רשימות תהליכים ב-XINU • במהלך הריצה, בכל רגע, חלק ניכר מתהליכים נמצאים במצב המתנה למשאבים (CPU, קלט, הודעה וכו') • מכיוון שמספר תהליכים עלולים להמתין לאותו משאב יש לנהל תור המתנה • כלל: התהליך יכול להופיע בכל זמן נתון בתור אחד • מספר התהליכים והתורים השונים הוא סופי מערכות הפעלה - תרגול 2
מימוש הרשימות • בעיה: הרשימות הנחוצים עבור המשאבים השונים הם מגוונים (FIFO,לפי עדיפות, תור הפרשים) עובדה זו מקשה על ניהול מערכת הרשימות • פתרון: מבנה אחיד לכל הרשימות שמספק את כל מגוון הדרישות ומאפשר אחידות בטיפול מערכות הפעלה - תרגול 2
מבנה רשומה • qprev -מצביע האיבר הבא • qnext -מצביע האיבר הקודם • qkey -מפתח, עדיפות של התהליך במקרה של תור ה- ready מערכות הפעלה - תרגול 2
הגדרת תור – q.h מבנה רשומה: struct qent { int qkey; int qnext; int qprev; }; מערכות הפעלה - תרגול 2
תורים ב-XINU • תור התהליכים המחכים למעבד • תור עדיפויות, הכנסה לפי מפתח – עדיפות • בתור עדיפויות התהליכים מסודרים בסדר עולה בכיוון ראש => זנב • הוצאה – איבר אחרון • תור התהליכים המחכים לסמפור – FIFO • הוצאה – מראש התור • תור הרדומים – תור ההפרשים מערכות הפעלה - תרגול 2
מימוש רשימהבעזרת מערך Key Next Prev 0 25 33 3 1 2 NPROC 140 32 3 ... איבר קודם NPROC-1 איבר הבא NPROC ... 2NSEM+4 Head=32 MININT 3 -1 Tail=33 MAXINT -1 1 מערכות הפעלה - תרגול 2
הגדרת תור – q.h Inline list manipulation procedures extern struct qent q[]; #define isempty(list) (q[(list)].qnext >= NPROC) #define nonempty(list) (q[(list)].qnext < NPROC) #define firstkey(list) (q[q[(list)].qnext].qkey) #define lastkey(tail) (q[q[(tail)].qprev].qkey) #define firstid(list) (q[(list)].qnext) מערכות הפעלה - תרגול 2
פונקציות לטיפול ברשימות • enqueueהכנסת איבר לסוף הרשימה • dequeueניתוק איבר מהרשימה והחזרת האינדקס שלו • insertהכנסת תהליך לרשימה לפי ערכו של key • getfirstהסרת התהליך הראשון ברשימה והחזרת האינדקס • getlast הסרת התהליך האחרון ברשימה והחזרת האינדקס • newqueueאיתחול רשימה חדשה במבנה ה-q מערכות הפעלה - תרגול 2
הוצאה מתור – queue.c #include <conf.h> #include <kernel.h> #include <q.h> int dequeue(item) int item; { struct qent *mptr; /* q entry for item */ mptr = &q[item]; q[mptr->qprev].qnext = mptr->qnext; q[mptr->qnext].qprev = mptr->qprev; return(item); } מערכות הפעלה - תרגול 2
הכנסה לפי מפתח – insert.c #include <conf.h> #include <kernel.h> #include <q.h> int insert(proc, head, key) int proc; /* process to insert */ int head; /* q index of head of list */ int key; /* key to use for this process */ { int next; /* runs through list */ int prev; next = q[head].qnext; while (q[next].qkey < key) /* tail key is MAXINT */ next = q[next].qnext; q[proc].qnext = next; q[proc].qprev = prev = q[next].qprev; q[proc].qkey = key; q[prev].qnext = proc; q[next].qprev = proc; return(OK); } מערכות הפעלה - תרגול 2
הוספה לסוף התור – queue.c #include <conf.h> #include <kernel.h> #include <q.h> int enqueue(item, tail) int item; int tail; { structqent *tptr; /* tail entry */ structqent *mptr; /* item entry */ tptr = &q[tail]; mptr = &q[item]; mptr->qnext = tail; mptr->qprev = tptr->qprev; q[tptr->qprev].qnext = item; tptr->qprev = item; return(item); } מערכות הפעלה - תרגול 2
הסרת התהליך הראשון ברשימה – getitem.c #include <conf.h> #include <kernel.h> #include <q.h> int getfirst(head) int head; /* q index of head of list */ { int proc; /* first process on the list */ if ((proc=q[head].qnext) < NPROC) return( dequeue(proc) ); else return(EMPTY); } מערכות הפעלה - תרגול 2
הסרת התהליך האחרון ברשימה – getitem.c #include <conf.h> #include <kernel.h> #include <q.h> int getlast(tail) int tail;/* q index of tail of list */ { int proc;/* last process on the list*/ if ((proc=q[tail].qprev) < NPROC) return( dequeue(proc) ); else return(EMPTY); } מערכות הפעלה - תרגול 2
איתחול רשימה חדשה – newqueue.c int newqueue() { struct qent *hptr; /* address of new list head */ struct qent *tptr; /* address of new list tail */ int hindex, tindex; /* head and tail indexes */ /* nextqueue is global variable */ hptr = &q[ hindex=nextqueue++ ]; /* giving next used q pos. */ tptr = &q[ tindex=nextqueue++ ]; hptr->qnext = tindex; hptr->qprev = EMPTY; hptr->qkey = MININT; tptr->qnext = EMPTY; tptr->qprev = hindex; tptr->qkey = MAXINT; return(hindex); } מערכות הפעלה - תרגול 2
טבלת תהליכים/ תורים יישום התורים של התהליכים מתבצע על ידי פונקציות ניהול תורים לכן: • אין בטבלת תהליכים מצביעים על סדר התורים • ניהול התורים נעשה בטבלת התורים (q) • לכל תהליך משוייכת רשומה בטבלת תהליכים וכן בטבלת התורים מערכות הפעלה - תרגול 2
טבלת תהליכים/ תורים • בטבלת התורים יש יותר רשומות מטבלת התהליכים.NPROC רשומות ראשונות בטבלת התורים משוייכות לתהליכים המקבילים בטבלת התהליכים. • שאר הרשומות בטבלת התורים משמשות כראשי/זנבות תורים שונים (Ready ,סמפורים, ו-sleeping) מערכות הפעלה - תרגול 2
תרגיל 3 יש למלא את המבנה של Q כפי שהוא נראה ברגע שהתכנית הגיע אל הנקודה המסומנת ב- /**/ #include <kernel.h> extern SYSCALL sleep(), wait(); int nop(); xmain() { int sem = screate(1); resume(create(sleep, INITSTK, 20, “pr1”, 1, 25)); resume(create(wait, INITSTK, 22, “pr2”, 1, sem)); resume(create(wait, INITSTK, 24, “pr3”, 1, sem)); resume(create(sleep, INITSTK, 21, “pr4”, 1, 10)); resume(create(nop, INITSTK, 20, “pr5”, 0)); resume(create(sleep, INITSTK, 20, “pr6”, 1, 30)); resume(create(wait, INITSTK, 20, “pr7”, 1, sem)); resume(create(nop, INITSTK, 20, “pr8”, 0)); create(sleep, INITSTK, 33, “pr9”, 1, 44); /**/ nop(); } nop() { while(1){}; } מערכות הפעלה - תרגול 2
תרגיל 3 pr3 pr7 SEM pr4 (10) pr1 (15) pr6 (5) SLEEP pr5 (20) 1 2 pr8 (20) READY מערכות הפעלה - תרגול 2