מערכות הפעלה תרגול 8 – סינכרוניזציה ב-Linux. מערכות הפעלה - תרגול 82 (c) ארז חדד 2003 תוכן התרגול מבוא לסינכרוניזציה ב-Linux סנכרון בין חוטי POSIX  mutex.

Slides:



Advertisements
Similar presentations
ממיבחניםC שאלות ++.
Advertisements

מבוא למדעי המחשב לתעשייה וניהול
מערכות הפעלה ( אביב 2004) חגית עטיה © 1 תהליכים - דייאט : חוטים  מוטיבציה  חוטי משתמש וחוטי מערכת  תמיכת מערכת ההפעלה  דוגמאות.
מערכות הפעלה ( אביב 2006) חגית עטיה © 1 תיאום בין תהליכים : שיטות מתקדמות  שימוש בחומרה למימוש מנעולים  מנגנוני מערכת הפעלה לתיאום : סמפורים, משתני תנאי.
מערכות הפעלה ( אביב 2004) חגית עטיה © 1 תיאום בין תהליכים : יסודות  דוגמאות לבעיות תיאום  הגדרות : קטע קריטי, מנעולים  אלגוריתם קופת - חולים.
מערכות הפעלה תרגול 4 – החלפת הקשר (context switch)
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב'
מערכות הפעלה תרגול 7 – ק/פ ותקשורת תהליכים ב-Linux.
תיאום בין תהליכים: שיטות מתקדמות
רקורסיות נושאי השיעור פתרון משוואות רקורסיביות שיטת ההצבה
מערכות הפעלה תרגול 5 – תהליכים ב-Linux (3). מערכות הפעלה - תרגול 52 (c) ארז חדד 2003 תוכן התרגול החלפת הקשר (context switch) ב-Linux יצירת תהליך חדש ב-Linux.
מערכות הפעלה תרגול 7 – ק/פ ותקשורת תהליכים ב-Linux.
חורף - תשס " ג DBMS, Design1 שימור תלויות אינטואיציה : כל תלות פונקציונלית שהתקיימה בסכמה המקורית מתקיימת גם בסכמה המפורקת. מטרה : כאשר מעדכנים.
מערכות הפעלה תרגול 3 – תהליכים ב-Linux (1). מערכות הפעלה - תרגול 32 (c) ארז חדד 2003 תוכן התרגול מבוא לתהליכים ב-Linux API לעבודה עם תהליכים מבוא לניהול.
מערכות הפעלה תרגול 9 – פסיקות ב-Linux. מערכות הפעלה - תרגול 92 (c) ארז חדד 2003 תוכן התרגול מבוא לפסיקות ב-Linux פסיקות ב-IA32:  סוגי הפסיקות  טבלת.
מערכות הפעלה תרגול 10 – זיכרון וירטואלי ב- Linux.
תכנות תרגול 4 שבוע : לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
הגנה במערכות מתוכנתות תרגול 1 – המחשב האישי הערה: שקפים אלה אינם מהווים תחליף לחומר התרגולים המפורסם באתר הקורס, ומשמשים כעזר הוראה בלבד.
מערכות הפעלה תרגול 6 – חוטים ב-Linux.
מערכות הפעלה תרגול 9 – פסיקות ב-Linux. מערכות הפעלה - תרגול 92 (c) ארז חדד 2003 תוכן התרגול מבוא לפסיקות ב-Linux פסיקות ב-IA32:  סוגי הפסיקות  טבלת.
מערכות הפעלה תרגול 3 – תהליכים ב-Linux (1). מערכות הפעלה - תרגול 32 (c) ארז חדד 2003 תוכן התרגול מבוא לתהליכים ב-Linux API לעבודה עם תהליכים מבוא לניהול.
חורף - תשס " ג DBMS, צורות נורמליות 1 צורה נורמלית שלישית - 3NF הגדרה : תהי R סכמה רלציונית ותהי F קבוצת תלויות פונקציונליות מעל R. R היא ב -3NF.
Map-Reduce Input: a collection of scientific articles on different topics, each marked with a field of science –Mathematics, Computer Science, Biology,
מערכות הפעלה ( אביב 2006) חגית עטיה © 1 תהליכים - דייאט : חוטים  מוטיבציה  חוטי משתמש וחוטי מערכת  תמיכת מערכת ההפעלה  דוגמאות.
מערכות הפעלה תרגול 9 – פסיקות ב-Linux. מערכות הפעלה - תרגול 92 (c) ארז חדד 2003 תוכן התרגול מבוא לפסיקות ב-Linux פסיקות ב-IA32:  סוגי הפסיקות  טבלת.
מערכות הפעלה ( אביב 2009) חגית עטיה © 1 תהליכים - דייאט : חוטים  מוטיבציה  חוטי משתמש וחוטי מערכת  תמיכת מערכת ההפעלה  דוגמאות ושימושים.
מערכות הפעלה תרגול 2 – קריאות מערכת ב-Linux. מערכות הפעלה - תרגול 22 (c) ארז חדד 2003 תוכן התרגול קריאה לפונקציות ב-Linux קריאה לשירותי מערכת ב-Linux.
Formal Specifications for Complex Systems (236368) Tutorial #6 appendix Statecharts vs. Raphsody 7 (theory vs. practice)
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
מערכות הפעלה תרגול 6 – חוטים ב-Linux. מערכות הפעלה - תרגול 62 (c) ארז חדד 2003 תוכן התרגול מבוא לחוטים ב-Linux כיצד גרעין Linux תומך בחוטים עבודה עם חוטים.
מערכות הפעלה ( אביב 2009) חגית עטיה ©1 מערכת קבצים log-structured  ה log הוא העותק היחיד של הנתונים  כאשר משנים בלוק (data, header) פשוט כותבים את הבלוק.
תהליכים  מהו תהליך ?  מבני הנתונים לניהול תהליכים.  החלפת הקשר.  ניהול תהליכים ע " י מערכת ההפעלה.
Multi-Cycle MIPS דוגמאות. דוגמה 1 נתון קטע הקוד הבא: begin:addi $v0, $zero, -1 loop:add $a0, $a0, $a0 addi$v0,$v0,1 bne $a0, $zero, loop הניחו כי בתחילת.
תהליכים - דייאט : חוטים  מוטיבציה  חוטי משתמש וחוטי מערכת  תמיכת מערכת ההפעלה  דוגמאות.
מבוא כללי למדעי המחשב תרגול 3. לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
מערכות הפעלה תרגול 1 - מבוא. מערכות הפעלה - תרגול 12 (c) ארז חדד 2003 ברוכים הבאים לקורס מערכות הפעלה! אדמיניסטרציה סקירה בסיסית של ארכיטקטורת IA32 (80386+)
מרץ 2002אלן אזאגורי ©1 חוטים Threads. מרץ 2002 אלן אזאגורי ©2עמוד נושאים הגדרות –חוטים –חוטים לעומת תהליכים תמיכת מערכת ההפעלה בחוטים דוגמאות –Mach –Windows.
1 ניהול תנועות חלק 2 Transaction Management Part 2.
תכנות תרגול 5 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
מערכות הפעלה תרגול 6 – חוטים ב-Linux. מערכות הפעלה - תרגול 62 (c) ארז חדד 2003 תוכן התרגול סינכרוניזציה בגרעין של Linux מבוא לחוטים ב-Linux כיצד גרעין.
עקרון ההכלה וההדחה.
יחס סדר חלקי.
מערכות הפעלה ( אביב 2006) חגית עטיה © 1 סיכום הקורס.
1 Formal Specifications for Complex Systems (236368) Tirgul Hazara.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
מערכות הפעלה תרגול 1 - מבוא. מערכות הפעלה - תרגול 12 (c) ארז חדד 2003 ברוכים הבאים לקורס מערכות הפעלה! אדמיניסטרציה סקירה בסיסית של ארכיטקטורת IA32 (80386+)
תיאום בין תהליכים : יסודות  דוגמאות לבעיות תיאום  הגדרות : קטע קריטי, מנעולים  אלגוריתם קופת - חולים.
מבוא למדעי המחשב תרגול 3 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
מבוא למדעי המחשב, סמסטר א ', תשע " א תרגול מס ' 1 נושאים  הכרת הקורס  פסאודו - קוד / אלגוריתם 1.
Markov Decision Processes (MDP) תומר באום Based on ch. 14 in “Probabilistic Robotics” By Thrun et al. ב"הב"ה.
מערכות הפעלה תרגול 1 - מבוא. מערכות הפעלה - תרגול 12 (c) ארז חדד 2003 ברוכים הבאים לקורס מערכות הפעלה! אדמיניסטרציה סקירה בסיסית של ארכיטקטורת IA32 (80386+)
עצים בינאריים - תזכורת דרגת צומת שורש עלה צומת פנימי מרחק בין 2 צמתים
מערכות הפעלה ( אביב 2004) חגית עטיה © 1 תהליכים  מהו תהליך ?  מבני הנתונים לניהול תהליכים.  החלפת הקשר.  ניהול תהליכים ע " י מערכת ההפעלה.
מתמטיקה בדידה תרגול 2.
מערכות הפעלה תרגול 4 – תהליכים ב-Linux (2). מערכות הפעלה - תרגול 42 (c) ארז חדד 2003 תוכן התרגול אלגוריתם זימון התהליכים ב-Linux  איך בוחרים, בכל נקודת.
1 Formal Specifications for Complex Systems (236368) Tutorial #3 Z introduction and notation (contd.); Birthday book example (Chapter 1 in the book)
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
פיתוח מערכות מידע Class diagrams Aggregation, Composition and Generalization.
תכנות אסינכרוני, תקשורת ופיתוח אפליקציות ל- Windows 8.1 ואפליקציות ל- Windows Phone 8 Control (Part II)
תכנות מכוון עצמים ושפת ++C וויסאם חלילי. TODAY TOPICS: 1. Function Overloading & Default Parameters 2. Arguments By Reference 3. Multiple #include’s 4.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 6. מפעל השעווה – לולאות  עד עכשיו  טיפלנו בייצור נרות מסוג אחד, במחיר אחיד  למדנו להתמודד עם טיפול במקרים שונים.
שיתוף PDT בין חוטים PDT Thread A Process Descriptor File Object 1 File Object 2 File 1 File 2 pthread_create Thread B Process Descriptor ה PDT משותף לכל.
Tirgul 12 Trees 1.
Computer Architecture and Assembly Language
ממשקים - interfaces איך לאפשר "הורשה מרובה".
מערכות הפעלה תרגול9 – פסיקות ב-Linux.
Asynchronous programming
הרצאה 21: Queue, Iterator & Iterable
תהליכים-דייאט: חוטים מוטיבציה חוטי משתמש וחוטי מערכת
Computer Architecture and Assembly Language
Presentation transcript:

מערכות הפעלה תרגול 8 – סינכרוניזציה ב-Linux

מערכות הפעלה - תרגול 82 (c) ארז חדד 2003 תוכן התרגול מבוא לסינכרוניזציה ב-Linux סנכרון בין חוטי POSIX  mutex  condition variable  סמפורים סינכרון נתונים בגרעין  הוראות אטומיות  spin locks  semaphores  חסימת פסיקות

מערכות הפעלה - תרגול 83 (c) ארז חדד 2003 מבוא לסינכרוניזציה ב-Linux הצורך בסינכרון הקשרי ביצוע שונים (כגון חוטים ותהליכים) הינו חיוני בכל מערכת הפעלה, כפי שראינו בדוגמאות רבות בהרצאות ותרגולים Linux מספקת מגוון רחב של מנגנונים לסנכרון בין חוטים ובין תהליכים, הן כשירות לקוד משתמש והן לצורך שימוש עצמי בספריות ובגרעין על-מנת להשתמש במנגנון כלשהו, כל החוטים/תהליכים חייבים לשתף פעולה  לדוגמה: אם חוט לא נועל מנעול בכניסה לקטע הקריטי, לא ניתן למנוע מהחוט לבצע את הקטע הקריטי בצורה לא מתואמת בתרגול זה נציג תחילה את עיקר מנגנוני הסנכרון עבור חוטים ברמת המשתמש (API) ונסיים בהסבר כללי על סנכרון בתוך הגרעין

מערכות הפעלה - תרגול 84 (c) ארז חדד 2003 סנכרון בין חוטי POSIX ב-Linux Linux Threads תומכת בחלק ממנגנוני הסנכרון המוגדרים ב-POSIX  mutexes, condition variables  תמיכה ב-monitors  סמפורים (POSIX b)..אך עבור חוטים בלבד (לא בין תהליכים)  אין תמיכה במנעולי קוראים-כותבים..אך ניתן לממש מנעולים כאלה, כפי שנראה בהמשך כזכור מהתרגול הקודם, Linux מספקת גם תמיכה בסמפורים בין תהליכים דרך System V IPC

מערכות הפעלה - תרגול 85 (c) ארז חדד 2003 מנעולי mutex (1) מנעול mutex מאפשר לחוט אחד בדיוק להחזיק בו (או "לנעול" אותו)  כל חוט אחר המבקש להחזיק במנעול ייחסם עד אשר המנעול ישוחרר  רק החוט המחזיק במנעול אמור לשחרר אותו ("בעלות" על המנעול) השימוש המקובל ב-mutex הוא להגנה על קטע קריטי של קוד ע"י נעילת המנעול בכניסה לקטע הקריטי ושחרורו בסופו בדרך-כלל מבוצעת הגנה על נתונים משותפים באמצעות הגדרת הקוד הניגש לנתונים כקטע קריטי סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 86 (c) ארז חדד 2003 מנעולי mutex (2) פעולות על mutex: #include אתחול mutex לפני השימוש: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr); פינוי mutex בתום השימוש int pthread_mutex_destroy(pthread_mutex_t *mutex);  הפעולה נכשלת אם ה-mutex מאותחל אבל נעול סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 87 (c) ארז חדד 2003 מנעולי mutex (3) נעילת mutex: int pthread_mutex_lock(pthread_mutex_t *mutex);  הפעולה חוסמת עד שה-mutex מתפנה ואז נועלת אותו נסיון לנעילת mutex: int pthread_mutex_trylock(pthread_mutex_t *mutex);  הפעולה נכשלת אם ה-mutex כבר נעול, אחרת נועלת אותו שחרור mutex נעול: int pthread_mutex_unlock(pthread_mutex_t *mutex); סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 88 (c) ארז חדד 2003 מנעולי mutex (4) פרמטרים:  mutex – המנעול עליו מבוצעת הפעולה  mutexattr – מגדיר את תכונות ה-mutex ב-Linux Threads מוגדרת רק תכונת "סוג" ה-mutex, המתבטאת בהתנהגות ה-mutex בנעילה ובשחרור, כמוצג בשקף הבא ברירת המחדל – NULL – mutex מסוג "מהיר" מומלץ לעבוד עם mutex מסוג "בודק שגיאות", כדי למנוע מצבים בעייתיים כגון אלו המסומנים באדום בשקף הבא פרטים כיצד לבחור את סוג ה-mutex ב-man pages ערך מוחזר: 0 בהצלחה, ערך אחר בכישלון סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 89 (c) ארז חדד 2003 מנעולי mutex (5) סוג ה-mutexנעילה חוזרת ע"י החוט המחזיק במנעול שחרור מנעול ע"י חוט שאינו מחזיק במנעול שחרור מנעול ע"י החוט המחזיק במנעול mutex מהירDEADLOCKמותר mutex רקורסיבימגדיל מונה נעילה עצמית ב-1 מותרמקטין מונה נעילה עצמית ב-1. ה- mutex נשאר נעול עד שהמונה מגיע ל-0 mutex בודק שגיאות כשלון מותר סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 810 (c) ארז חדד 2003 מנעולי mutex (6) pthread_mutex_t m; int count; void update_count() { pthread_mutex_lock(&m); count = count * 5 + 2; pthread_mutex_unlock(&m); } להלן דוגמה המשתמשת ב-mutex: int get_count() { int c; pthread_mutex_lock(&m); c = count; pthread_mutex_unlock(&m); return c; } 1.מדוע צריך להגן על הגישה ל-count בתוך update_count()? כדי למנוע שיבוש ערך count בעדכונים מחוטים שונים. 2.מדוע צריך להגן על הגישה ל-count בתוך get_count()? כדי למנוע קבלת תוצאות חלקיות הנוצרות במהלך העדכון שימו לב! גם אם ביטוי ההגדלה היה count++, לא מובטח שהקוד הנפרש באסמבלר הינו אטומי, ולכן יש להפעיל מנגנון סנכרון לפי הצורך. סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 811 (c) ארז חדד 2003 משתני תנאי (1) mutex מאפשר מדיניות סנכרון פשוטה של חוט אחד לכל היותר הניגש לקטע הקריטי בכל זמן נתון  ניתן לממש סנכרון מורכב יותר בכל מיני שיטות על-מנת לממש בצורה מובנית אובייקט סנכרון מכל סוג שהוא, משתמשים במשתני תנאי (condition variables)  משתנה תנאי מאפשר לחוט להמתין לכל ארוע שהוא המוגדר ע"י המתכנת  משתנה תנאי תמיד קשור ל-mutex מסוים  mutex + 0 או יותר משתני תנאי = monitor סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 812 (c) ארז חדד 2003 משתני תנאי (2) פעולות על משתני תנאי #include איתחול משתנה תנאי לפני השימוש: int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); פינוי משתנה תנאי בסיום השימוש: int pthread_cond_destroy(pthread_cond_t *cond);  הפעולה נכשלת אם יש חוטים הממתינים על משתנה התנאי סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 813 (c) ארז חדד 2003 משתני תנאי (3) המתנה על משתנה תנאי: int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);  החוט הממתין חייב להחזיק במנעול mutex לפני הקריאה  פעולה אטומית: משחררת את המנעול mutex ומעבירה את החוט להמתין על משתנה התנאי שחרור חוט ממתין על משתנה תנאי: int pthread_cond_signal(pthread_cond_t *cond);  אם אין חוט שממתין כרגע על משתנה התנאי cond – הפעולה חסרת השפעה (ואינה נזכרת הלאה) סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 814 (c) ארז חדד 2003 משתני תנאי (4)  אם קיימים חוטים ממתינים על משתנה התנאי cond – אחד החוטים הממתינים (הגינות לא מובטחת) מפסיק להמתין על משתנה התנאי, ויחזור לפעילות (יעבור את ה- pthread_cond_wait()) לאחר שינעל מחדש את ה-mutex (סגנון Mesa) שחרור כל החוטים הממתינים על משתנה תנאי: int pthread_cond_broadcast(pthread_cond_t *cond);  אם אין חוט שממתין כרגע על משתנה התנאי cond – הפעולה חסרת השפעה (ואינה נזכרת הלאה)  אם קיימים חוטים ממתינים על משתנה התנאי cond – כל החוטים הממתינים מפסיקים להמתין על משתנה התנאי, ויחזרו לפעילות בזה אחר זה (בסדר כלשהו, לאו דוקא הוגן) לאחר שינעלו מחדש את ה-mutex סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 815 (c) ארז חדד 2003 משתני תנאי (5) פרמטרים:  cond – משתנה התנאי עליו מבוצעת הפעולה  cond_attr – מגדיר את תכונות משתנה התנאי ב-Linux Threads אין משמעות לפרמטר זה. ערך NULL  mutex – המנעול אליו משויך משתנה התנאי בביצוע pthread_cond_wait() ערך מוחזר: 0 בהצלחה, ערך אחר בכישלון  הפונקציות init, signal, broadcast, wait תמיד מחזירות ערך הצלחה סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 816 (c) ארז חדד 2003 קישור בין אירוע ומשתנה תנאי (1) הדרך הפשוטה ביותר לקשר בין אירוע המציין קיום מצב רצוי כלשהו למשתנה תנאי היא בקוד כדלקמן:  אצל הממתין לאירוע (החוט שרוצה להתקדם רק כאשר יושג המצב הרצוי): if pthread_cond_wait(, );  אצל יוצר האירוע (החוט שיוצר את המצב הרצוי ומסמן לחוטים הממתינים להתקדם): if אם זה ודאי ifאפשר לוותר על ה- pthread_cond_signal( ); אבל.. בעיה! (בשקף הבא)

מערכות הפעלה - תרגול 817 (c) ארז חדד 2003 קישור בין אירוע ומשתנה תנאי (2) פעולת signal לא מאפשרת לחוט הממתין להמשיך מיד  החוט הממתין צריך תחילה לנעול את ה-mutex מחדש (סגנון Mesa) לכן, ייתכן שלפני שהחוט הממתין ינעל את ה-mutex מחדש יספיק להכנס חוט נוסף שישנה את הנתונים כך שהמצב הרצוי כבר לא מתקיים  במימוש לפי סגנון Hoare (נדיר מאוד), החוט שמבצע signal גם מוותר על המנעול ומעביר אותו לחוט הממתין, כך שאם הנתונים מוגנים ע"י המנעול, מצבם אינו יכול להשתנות והחוט הממתין יכול להמשיך ללא הפרעה במצב הרצוי.  מצד שני, בסגנון Hoare החוט שביצע signal "נענש" על כך שסייע לחוט אחר להתקדם בכך שהוא מוכרח לוותר על ההתקדמות שלו עצמו ולעבור להמתין על המנעול עד שישוחרר

מערכות הפעלה - תרגול 818 (c) ארז חדד 2003 קישור בין אירוע ומשתנה תנאי (3) דוגמה מההרצאה – מימוש תור pthread_mutex_t qlock; pthread_cond_t notEmpty; /* … initialization code … */ void enqueue(item x) { pthread_mutex_lock(&qlock); /* … add x to queue … */ pthread_cond_signal(&notEmpty); pthread_mutex_unlock(&qlock); } item dequeue() { pthread_mutex_lock(&qlock); if pthread_cond_wait(&notEmpty, &qlock); /* … remove item from queue … */ pthread_mutex_unlock(&qlock); /*.. return removed item */ }

מערכות הפעלה - תרגול 819 (c) ארז חדד 2003 קישור בין אירוע ומשתנה תנאי (4) נניח, לפי הדוגמה שהתור ריק וחוט t1 קורא ל-dequeue(), ולכן ממתין כעת חוט t2 קורא ל-enqueue(), מכניס איבר לתור ומבצע signal  חוט t1 עובר להמתין לשחרור המנעול כעת מגיע חוט t3, וקורא ל-dequeue()  חוט t3 נחסם בהמתנה למנעול בתחילת הקוד חוט t2 משחרר את המנעול ומסיים את enqueue() חוט t3 מקבל את המנעול, נכנס, מוציא איבר ומסיים חוט t1 מקבל את המנעול, ממשיך לבצע את הקוד ומנסה להוציא איבר מתור ריק!

מערכות הפעלה - תרגול 820 (c) ארז חדד 2003 קישור בין אירוע ומשתנה תנאי (5) ממה נבעה הבעיה בדוגמה?  מכך שהתנאי של האירוע לא נבדק אחרי ה-wait כיצד ניתן לפתור את הבעיה?  ע"י בדיקה חוזרת של תנאי האירוע והמתנה נוספת לפי הצורך. לדוגמה: while pthread_cond_wait(…) האם הבעיה יכלה לקרות גם אם המנעול היה הוגן (תור FIFO)?  כן! אם t3 היה קורא ל-dequeue() ומחכה למנעול לפני ש-t2 הגיע ל-signal האם הבעיה יכלה לקרות אם ה-monitor היה בסגנון Hoare?  לא! כי t1 היה מקבל את המנעול לפני t3

מערכות הפעלה - תרגול 821 (c) ארז חדד 2003 בעיית הקוראים-כותבים (1) תזכורת מההרצאה: בעית הקוראים-כותבים מתארת מצב נפוץ בו קיים משאב עבורו מוגדרות שתי פעולות: "קריאה" ו"כתיבה"  מספר חוטים קוראים יכולים לגשת למשאב בו-זמנית  חוט כותב זקוק לגישה בלעדית למשאב בשקפים הבאים נדגים כיצד ניתן לממש מנגנון סנכרון שכזה באמצעות monitor סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 822 (c) ארז חדד 2003 בעיית הקוראים-כותבים (2) הגדרת המנגנון: #include int number_of_readers; pthread_cond_t readers_condition; int number of writers; pthread_cond_t writers_condition; mutex_t global_lock; void readers_writers_init() { number_of_readers = 0; pthread_cond_init(&readers_condition, NULL); number_of_writers = 0; pthread_cond_init(&writers_condition, NULL); pthread_mutex_init(&global_lock, NULL); } מספר החוטים שקוראים מהמשאב מספר החוטים שכותבים למשאב אירוע: מותר לקרוא אירוע: מותר לכתוב סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 823 (c) ארז חדד 2003 בעיית הקוראים-כותבים (3) void reader_lock() { pthread_mutex_lock(&global_lock); while (number_of_writers > 0) pthread_cond_wait(&readers_condition, &global_lock); number_of_readers++; pthread_mutex_unlock(&global_lock); } void readers_unlock() { pthread_mutex_lock(&global_lock); number_of_readers--; if (number_of_readers == 0) pthread_cond_signal(&writers_condition); pthread_mutex_unlock(&global_lock); } סנכרון בין חוטי POSIX ב-Linux צריך לבדוק את תנאי הבדיקה גם לאחר wait

מערכות הפעלה - תרגול 824 (c) ארז חדד 2003 בעיית הקוראים-כותבים (4) void write_lock() { pthread_mutex_lock(&global_lock); while ((number_of_writers > 0) || (number_of_readers > 0)) pthread_cond_wait(&writers_condition, &global_lock); number_of_writers++; pthread_mutex_unlock(&global_lock); } void write_unlock() { pthread_mutex_lock(&global_lock); number_of_writers--; if (number_of_writers == 0) { pthread_cond_broadcast(&readers_condition); pthread_cond_signal(&writers_condition); } pthread_mutex_unlock(&global_lock); } למעשה, אין צורך ב-if.. עדיפות לקוראים ממתינים על-פני כותבים ממתינים סנכרון בין חוטי POSIX ב-Linux צריך לבדוק את תנאי הבדיקה גם לאחר wait

מערכות הפעלה - תרגול 825 (c) ארז חדד 2003 סמפורים (1) Linux Threads תומכת בסמפורים כלליים תזכורת מההרצאה:  בסמפור מוגדרות שתי פעולות בסיסיות: wait ו-post בהרצאה קראנו ל-post בשם signal, אך כאן נימנע משם זה כדי לא לבלבל עם signal של משתנה תנאי  לסמפור יש מונה. פעולת wait מורידה את ערך המונה ופעולת post מעלה אותו  כאשר מונה הסמפור אינו גדול מ-0, פעולת wait חוסמת את החוט הקורא עד שחוט אחר כלשהו יבצע post ויעלה את ערך המונה מעל 0 סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 826 (c) ארז חדד 2003 סמפורים (2)  ניתן להתייחס לסמפור כאל מאגר של מספר יחידות של משאב פעולת wait ממתינה עד שיש יחידה פנויה ואז "צורכת" אותה. פעולת post מחזירה יחידה למאגר בתום השימוש  כפי שראינו בהרצאה, ניתן לפתור עם סמפורים את בעיית היצרן-צרכן  אם סמפור מאותחל עם מונה בערך 1 (סמפור בינארי), ניתן להשתמש בו על-מנת להגן על קטע קריטי (ליצור מניעה הדדית בין החוטים הניגשים) עם זאת, סמפור בינארי אינו מנעול mutex, משום שכל חוט יכול לבצע post על סמפור, גם אם לא ביצע wait על הסמפור קודם לכן (אין "בעלות" על הסמפור) סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 827 (c) ארז חדד 2003 סמפורים (3) סמפור ממומש ב-Linux Threads בקירוב כפי שהודגם בהרצאה:  לכל סמפור יש מונה, תור ומנעול שתפקידו להגן על הקוד של הפעולות של הסמפור (  פעולות אטומיות)  פעולת wait: אם המונה גדול מ-0, מקטינה אותו ב-1, אחרת החוט נכנס להמתנה בתור  פעולת post: אם תור הממתינים לא ריק, מוציאה ומעירה את החוט הראשון בתור, אחרת מגדילה את המונה ב-1  תור הממתינים הוגן (FIFO) עד כדי עדיפות, כלומר חוט בעדיפות גבוהה יצא מהתור לפני חוט בעדיפות נמוכה סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 828 (c) ארז חדד 2003 סמפורים (4) פעולות על סמפורים: #include  לא לשכוח לקשר לספרייה pthread! אתחול סמפור לפני השימוש: int sem_init(sem_t *sem, int pshared, unsigned int value); פינוי סמפור בתום השימוש: int sem_destroy(sem_t *sem); סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 829 (c) ארז חדד 2003 סמפורים (5) ביצוע wait על סמפור: int sem_wait(sem_t *sem); ביצוע post על סמפור: int sem_post(sem_t *sem); גרסה לא-חוסמת של wait: int sem_trywait(sem_t *sem);  אם המונה של הסמפור אינו גדול מ-0, חוזרת מיד ונכשלת קריאת ערך מונה הסמפור: int sem_getvalue(sem_t *sem, int *sval); סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 830 (c) ארז חדד 2003 סמפורים (6) פרמטרים:  sem – הסמפור עליו מבוצעות הפעולות  pshared – אם ערכו גדול מ-0, מציין שהסמפור יכול להיות משותף למספר תהליכים. תכונה זו אינה נתמכת, ולכן נציב בו 0 קבוע  value – ערכו ההתחלתי של מונה הסמפור  sval – מצביע למקום בו יאוחסן ערך מונה הסמפור ערך מוחזר: 0 בהצלחה, (1-) בכישלון  הפונקציות sem_wait() ו-sem_getvalue() תמיד מצליחות סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 831 (c) ארז חדד 2003 סמפורים – שאלת דוגמה ממבחן נתונה הסדרה הבאה: האיברים נתונים וגלובליים בתהליך יש לחשב את ע"י n חוטים בתהליך, כך שהחוט ה-i יחשב את האיבר הראו כי ניתן לממש את החישוב ע"י סמפורים כלליים (הניחו כי n הוא ריבוע מספר שלם)  ציינו את איתחול הסמפורים ופעולות החוטים על הסמפורים סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 832 (c) ארז חדד 2003 סמפורים – פתרון שאלת הדוגמה בהנחה ש- כאשר A>1 הוא מספר שלם כלשהו, נסדר את החוטים בריבוע לכל חוט במטריצה יש אינדקס שורה ועמודה נחזיק סמפור אחד לכל עמודה, בסימון כנ"ל סמפור לכל שורה: אתחול: סמפור מאותחל ל-A, סמפור מאותחל ל-1 ושאר הסמפורים מאותחלים ל-0 חישוב: השלימו לבד היכן ממוקמת המטריצה הנ"ל? סנכרון בין חוטי POSIX ב-Linux

מערכות הפעלה - תרגול 833 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (1) ניתן לראות את גרעין מערכת ההפעלה כ"שרת" המקבל "בקשות" בצורת פסיקות מהתקן חומרה חיצוני או מתוכנה פנימית בעקבות כל "בקשה" הגרעין מבצע רצף של קוד המטפל בבקשה. רצף קוד זה נקרא מסלול בקרה בגרעין (Kernel Control Path)  לדוגמה: טיפול בקריאת מערכת מסוימת של תהליך מסוים הוא מסלול בקרה שכזה המתחיל בפונקציה system_call() ומסתיים ב-ret_from_sys_call(), כפי שראינו בתרגולים קודמים למסלול בקרה אין descriptor כי הוא לא חוט או תהליך – זהו פשוט מסלול ביצוע הוראות בתוך הגרעין

מערכות הפעלה - תרגול 834 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (2) המעבד יכול למתג בין מספר מסלולי בקרה בתוך הגרעין בעקבות תסריט כגון:  מתבצעת החלפת הקשר בין תהליכים בגרעין  במהלך ביצוע מסלול בקרה לאחר פסיקה כלשהי, קורית פסיקה נוספת המחייבת תחילת ביצוע מסלול בקרה נוסף כמו כן, במערכת מרובת מעבדים, מספר מסלולי בקרה מתבצעים במקביל בגרעין לפיכך, מבני הנתונים בגרעין עלולים להשתבש כתוצאה מגישה לא מתואמת ממספר מסלולי בקרה שונים ולכן יש להגן עליהם  גישה לא מתואמת ממספר מקומות יוצרת מירוץ (race) – מצב שבו הנתונים עלולים להגיע למצב לא תקין במהלך הביצוע, כגון ערכים שגויים, מצביעים למקומות לא מתאימים וכו'.

מערכות הפעלה - תרגול 835 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (3) ישנם גורמים שמפשטים מעט את הבעיה:  גרעין Linux הוא non-preemptive, כלומר תהליך הנמצא ב- kernel mode יוותר על המעבד רק מרצונו שלו (קריאה ל- schedule()) ולא מאילוץ של המערכת  אם מסלול בקרה של תהליך נקטע ע"י מסלול בקרה של טיפול בפסיקה, מסלול הבקרה של התהליך ימשיך לאחר סיום הטיפול בפסיקה מסלולי בקרה מתבצעים בצורה מקוננת  מסלול בקרה של טיפול בפסיקה שאינה קריאת מערכת אינו יכול להקטע ע"י מסלול בקרה של טיפול בקריאת מערכת

מערכות הפעלה - תרגול 836 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (4) לפיכך, במערכת עם מעבד יחיד, למשל, קריאת מערכת שאינה חוסמת מתבצעת בצורה אטומית ביחס לקריאות מערכת אחרות, כך שאם היא לא משתמשת במבני נתונים הנגישים ממסלולי בקרה של פסיקות אחרות, היא יכולה לגשת לנתונים בבטחה עם זאת, קריאת מערכת שחוסמת (מוותרת על המעבד) חייבת להשאיר את מבני הנתונים בגרעין תקינים לפני שתוותר על המעבד, ובחזרה לביצוע חייבת לבדוק שהנתונים לא שונו ע"י מסלול בקרה אחר  למשל: להוסיף נתונים לחוצץ וגם לעדכן את גודל החוצץ..וכמובן, קריאות מערכת אינן אטומיות לעולם במערכת מרובת מעבדים – סיבוך נוסף..

מערכות הפעלה - תרגול 837 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (5) סנכרון גישה לנתונים ממסלולי בקרה שונים מבוצע באמצעות קטעים קריטיים בגרעין  קטע קריטי בגרעין הוא קטע קוד שחייב להתבצע בשלמותו ע"י מסלול הבקרה שנכנס אליו לפני שכל מסלול בקרה אחר יוכל להכנס לקטע זה ההגנה על קטעים קריטיים מבוצעת במגוון אמצעים כגון:  הוראות אטומיות (Atomic Operations): פעולות עדכון נתונים (Read- Modify-Write) המבוצעות באופן אטומי ברמת המכונה ביחס לכל המעבדים הקטע הקריטי מוכל בהוראה האטומית הוראות אטומיות מנצלות תמיכה של החומרה, כגון הוראת lock (IA32) הנועלת את ערוץ הגישה של כל המעבדים לזיכרון (memory bus) עד לסיום ההוראה שאחריה דוגמה להוראה אטומית: test_and_set_bit(), המדליקה ביט ומחזירה את ערכו הקודם

מערכות הפעלה - תרגול 838 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (6)  Spin Locks: למעשה, מנעול הממומש כ-busy wait קיים רק במערכת מרובת מעבדים, מפני שאילולי כן, במערכת מעבד יחיד מסלול בקרה היה נתקל ב-spin lock נעול, והיה עלול להמתין לנצח – כי המסלול שהחזיק את המנעול נקטע ואינו יכול לחזור לרוץ עד שהממתין יסיים למעשה, busy wait הוא המתנה יעילה כאשר מדובר בנעילות קצרות מאוד כפי שקורה בגרעין, מפני שאין את התקורה של של כניסה ויציאה מהמתנה טיפוס spinlock_t בקובץ גרעין include/linux/spinlock.h קיימת גרסה נוספת: read-write spin locks (טיפוס rwlock_t) המממשת מנעולי קוראים-כותבים ב-busy wait  סמפורים כלליים: מימוש נפרד המיועד לשימוש פנימי בגרעין בלבד המתנה של מסלול בקרה לסמפור גורמת להמתנת התהליך שרץ כרגע. לכן, סמפורים משמשים בקריאות מערכת ואינם משמשים בטיפול בפסיקות אחרות (אחרת תהליך נכנס להמתנה מסיבה שאינה תלויה בו) טיפוס struct semaphore בקובץ גרעין include/asm-i386/semaphore.h

מערכות הפעלה - תרגול 839 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (7)  חסימת פסיקות מקומית (Local Interrupt Disabling): חסימת הפסיקות במעבד הנוכחי בו מתבצע מסלול הבקרה אחד האמצעים החשובים ביותר להגנה על קטע קריטי – מאפשר למסלול בקרה להתקדם ללא חשש מקטיעה ע"י מסלולי בקרה של פסיקות אחרות חסימת הפסיקות לזמן רב עלולה לגרום לפגיעה בביצועים ולאבדן פסיקות חיוניות אמצעי זה אינו מספיק במערכות מרובות מעבדים, שם בד"כ משלבים אותו עם spin locks בסיום הקטע הקריטי משוחזר ערך דגל הפסיקות מלפני כיבויו, מפני שהדגל לא דלק בהכרח לפני הכיבוי. להלן רצף אופייני (הפעולות הן מאקרו):

מערכות הפעלה - תרגול 840 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (8) __save_flags(old); __cli(); /* clear interrupt flag (IF) */ __resotre_flags(old); כל המאקרו שצוינו נמצאים בקובץ הגרעין include/asm- i386/system.h המאקרו __cli() ו-__sti() מכילים קריאות להוראות המכונה cli ו-sti המבצעות, בהתאמה, חסימה ואפשור של דגל הפסיקות במעבד (IF)  מאקרו אלה נקראים כיום גם local_irq_disable() ו-local_irq_enable()  קיימת גם חסימת פסיקות בכל המעבדים (Global Interrupt Disabling), שהיא בשימוש נדיר מאוד (כגון לאיתחול התקני חומרה מסוימים) הגדרת המאקרו באותו קובץ גרעין כמו בחסימה מקומית עם אותם שמות מאקרו אך ללא תחילית "__"

מערכות הפעלה - תרגול 841 (c) ארז חדד 2003 סינכרוניזציה בתוך גרעין Linux (9) דוגמאות לשימוש במנגנון סנכרון:  מונה שימוש במשאב (reference counters) מוגדל כאשר תהליך מקבל את המשאב לשימוש ומוקטן כאשר התהליך מסיים להשתמש במשאב. מכיוון שמשאבים יכולים להיות בשימוש ע"י מספר תהליכים, מתבצעות פעולות ההגדלה וההקטנה כהוראות אטומיות  מבני נתונים שנגישים ממסלולי בקרה של פסיקות שונות מוגנים בשילוב של חסימת פסיקות מקומית + spin lock חסימת הפסיקות המקומית דרושה על-מנת למנוע מסלולי בקרה אחרים באותו מעבד מלהכנס לקטע הקריטי  כפי שהוסבר קודם, סמפור ו-spin lock לא מתאימים למטרה זו ה-spin lock דרוש על-מנת למנוע ממסלולי בקרה במעבדים אחרים מלהכנס לקטע הקריטי, מבלי לחסום פסיקות בכולם לחלוטין