08-04-2005, 12:30
|
|
|
חבר מתאריך: 20.12.01
הודעות: 20,962
|
|
אז איך תפתור את בעיית הסנכרון במקרה הזה?
במערכת עם מעבד אחד, אם יש לנו שני ת'רדים שניגשים לאותו זכרון, אפשר להגן עליו
באמצעות מנגנונים של מערכת ההפעלה(כמו סמפורים, לדוגמה), או, במידה ורוצים "לעשות
את זה לבד", משתמשים בפקודה XCHG(נדמה לי שזה השם).
העניין הוא כזה: אם יש לנו כתובת מסויימת שגם ת'רד א' וגם ת'רד ב' ניגשים אליה (למטרות
קריאה וכתיבה), עלול להווצר מצב שבו ת'רד א' קורא ממנה מידע, ובאותו זמן ת'רד ב' כותב
עליו מידע חדש, כך שת'רד א' יקרא חצי מידע ישן/חצי מידע חדש, לדוגמה (או ששניהם יכתבו
לאותה כתובת בו-זמנית). פתרון שאפשר להעלות על הדעת הוא שימוש בביט גישה מיוחד
לפני תחילת המידע עצמו: לפני שת'רד ב' מתחיל לכתוב, הוא קובע את הביט ל-1, ולפני שת'רד
א' ניגש למידע הוא בודק את הביט. מכיוון שהוא רואה שהביט נקבע ל-1, הוא יודע שאסור לו
לגשת לכתובת הזו. ברגע שת'רד ב' מסיים, הוא קובע את הביט ל-0, ועכשיו ת'רד א' יודע
שמותר לו לגשת למידע שם(והוא כמובן קובע את הביט ל-1 לפני שהוא מתחיל לעבוד).
הבעיה: יכול להיות מצב שבו ת'רד ב' מתחיל לעבוד, בודק שביט הגישה שווה ל-0, ומבין שמותר
לו לגשת לכתובת מסויימת. באותו רגע מתרחשת פסיקה והשליטה מועברת לת'רד ב', שגם
הוא בודק את ביט הגישה, וגם הוא רואה שהוא קבוע ל-0, ומבין שגם לו מותר לגשת למידע....
מה שקורה עכשיו זה ששניהם יקבעו את הביט ל-1, ושניהם יעבדו עם המידע, וידפקו אחד
תש'ני... לא טוב.
הפתרון הוא פקודת אסמבלי מיוחדת, שנקראת XCHG למיטב זכרוני, וכשמה כן היא: הפקודה
הזו מחליפה(exchanges) בין כתובת מסויימת לאוגר. כל היופי הוא שמדובר בפקודת אסמבלי
אחת, ולא בכמה פקודות כמו שהיה למעלה.
ת'רד ב' מכניס לאוגר מסויים את הערך 1, ואז מבצע XCHG עם ביט הגישה. כעת הוא בודק
את ערך האוגר: אם באוגר רשום 0, זה אומר שלפני ה-XCHG היה 0 בביט הגישה, ומותר
לגשת לאותה כתובת(ועכשיו כבר כתוב שם 1 בגלל ה-XCHG); אם רשום באוגר 1, זה אומר
שלפני ה-XCHG היה בביט הגישה 1 - ואסור לפעול עם הכתובת, אבל ביט הגישה לא השתנה,
היה 1 ונשאר 1. בעזרת XCHG הבדיקה האם בביט רשום 0, וכתיבת 1 לתוכו לא מתבצעות
בנפרד, ולא יכולה להתרחש פסיקה "באמצע הפקודה".
עד כאן הכל טוב - אבל מה יקרה כשיהיו לנו שני מעבדים ושני ת'רדים שיתבצעו בנפרד עליהם?
כאן הטריק של XCHG כבר לא פועל - כי שני המעבדים יכולים לבצע XCHG בו-זמנית.
איך פותרים את הבעיה הזו במערכת מרובת מעבדים?
|