במדעי המחשב, סֶמָפוֹר (מיוונית עתיקה: (σῆμα (סמא) – סימן, φωρος (פורוס) – נושא; באנגלית: Semaphore; לפי האקדמיה ללשון העברית אַתָּת[1]) הוא מנגנון לסנכרון מספר תהליכים הפועלים במחשב במקביל, ומטרתו לפתור את בעיית המניעה ההדדית (Mutual exclusion).
הסמפור הוא למעשה הרחבה של מנגנון המנעול, והוא יכול לקבל ערכים שלמים אי שליליים. סמפור בינארי פועל למעשה כמו מנעול.
מנגנון הסמפור הומצא על ידי מדען המחשב ההולנדי אדסחר דייקסטרה באמצע שנות ה-60 של המאה ה-20, והוא נמצא בשימוש נרחב במערכות הפעלה רבות.
תיאור הבעיה ופתרונה באמצעות לולאה
כאשר קיימים מספר תהליכים אשר חולקים ביניהם משאבים משותפים (למשל תא זיכרון או קובץ), יכולה להיווצר בעיית אמינות של המידע במקרה ששני התהליכים ניגשים למשאב משותף ומשנים את תוכנו ללא סדר.
פתרון של הבעיה נעשה על ידי הגדרת "קטע קריטי", אשר כל אחד מן התהליכים יוכל להיכנס אליו או לצאת ממנו רק לאחר ביצוע מספר פעולות, שמטרתן להבטיח כי בכל נקודת זמן רק תהליך אחד נמצא בתוך קטע הקוד הקריטי שלו.
פתרונות לבעיה כוללים תמיד המתנה עד אשר תנאי כלשהו יתקיים, כתנאי לכניסת התהליך לקטע הקריטי (עד אשר תנאי כלשהו יתקיים, אל תבצע פעולה). מימוש המתנה כזו יעשה על ידי לולאת while. הבעיה בפתרון זה היא שההמתנה בתוך הלולאה דורשת זמן מעבד. בנוסף לכך, קיימת סכנה כי בעת ביצוע קטע הקוד לכניסה לקטע הקריטי, אשר מורכב ממספר פקודות (או מפקודה אחת אשר מורכבת ממספר פקודות מכונה), "ייחטף" המעבד מהתהליך וכך עלול לקרות מצב שבו המשך ביצוע התוכנית מסתמך על נתונים לא מעודכנים.
אחד הפתרונות שהוצעו לבעיה היה הוספת רכיב חומרה, המבצע סדרת פקודות בצורה אטומית שאיננה מאפשרת למערכת ההפעלה (או למתזמן) לקטוע את ביצוע סדרת הפקודות; אולם פתרון זה לא מנע את בזבוז משאבי המעבד בהמתנה לקיום התנאי לכניסה לקטע הקריטי.
פתרון הבעיה באמצעות סמפור
כיום נהוג לפתור בעיה זו על ידי שימוש בסמפור: מעין דגל (flag) אשר כדי לשנות את ערכו התהליך נדרש לבקש זאת ממערכת ההפעלה. אם הדגל כבר "נתפס" על ידי תהליך אחר, מערכת ההפעלה תעביר את התהליך ל"מצב שינה", ו"תעיר" אותו על ידי משלוח פסיקה ברגע שהדגל "משוחרר" על ידי התהליך שתפס אותו.
בצורה זו מתאפשר סנכרון ללא בזבוז זמן מעבד, וכן מובטח לנו כי מערכת ההפעלה מפקחת על מצב הדגל ושינוי של ערכו מבוצע בצורה אטומית (לא ניתן לחטוף לתהליך את המעבד בזמן שינוי ערך הדגל). במקרה שהסמפור איננו "הוגן", קרי, איננו משחרר לפי הסדר בו ניסו לתפוס אותו, קיימת בעיה של הרעבה.
אופן פעולת הסמפור
הסמפור הוא משתנה היכול לקבל ערכים שלמים לא שליליים (במקרה של סמפור בינארי הוא יכול לקבל שני ערכים בלבד, 0 ו־1).
על הסמפור מוגדרות שתי פעולות אטומיות:
- אם ערך הסמפור גדול מ־0 הקטן אותו ב־1 והמשך, אחרת המתן עד שיהיה גדול מ־0, ואז הקטן אותו ב־1 והמשך.
- הגדל את ערך הסמפור ב־1.
דוגמה לשימוש בסמפור בינארי על מנת לפתור את בעיית המניעה ההדדית כאשר קיימים שני תהליכים החולקים משאב משותף. הסמפור יאותחל ל־1. לפני כניסה של כל תהליך לקטע הקריטי תתבצע הפעולה הראשונה, וביציאה ממנו הפעולה השנייה.
ראו גם
קישורים חיצוניים
הערות שוליים