תהליכון

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה אל: ניווט, חיפוש
תהליך עם שני תהליכונים

תהליכוןאנגלית: Thread of execution, או בקיצור: Thread) ולעתים חוט, פתיל ריצה או נים הוא מושג במדעי המחשב המשמש במערכות הפעלה כדי לתאר הקשר ריצה במרחב כתובות.

מערכות הפעלה מודרניות מאפשרות לנהל במסגרת ריצה של תהליך (Process) מספר תהליכונים הרצים במקביל במרחב כתובות אחד. במערכות אלו כל תהליך חדש מתחיל את ביצועו באמצעות 'תהליכון ראשי' אשר עשוי בהמשך ליצור תהליכונים נוספים. מנגנון הריצה באמצעות תהליכונים מאפשר לספק למשתמש במערכת ההפעלה מהירות תגובה ורציפות פעולה כאשר התהליך (יישום) מבצע כמה משימות במקביל.

ריצה במקביל[עריכת קוד מקור | עריכה]

במחשבים בעלי מעבד בודד אין למעשה ריצה של קוד במקביל, כך שתחושת המקביליות מתקבלת באמצעות קפיצה מריצה בהקשר של תהליכון אחד לריצה בהקשר של תהליכון שני. קפיצה זו, המכונה החלפת הקשר (Context switch), מבצעת מעין צילום מצב של המעבד (אוגרים וכדומה) לפני נטישה של תהליכון מסוים כדי לאפשר מעבר לתהליכון אחר וחזרה לתהליכון הקודם בהמשך. פעולת החלפת ההקשר היא פעולה יקרה יחסית מבחינת זמן עיבוד ועל כן משתדלים מפתחי מערכות הפעלה לשפר את זמן ההחלפה ואף לשלב אלגוריתמי ייעול לצמצום מספר ההחלפות.

תקלות בתכנות מבוסס ריבוי תהליכונים[עריכת קוד מקור | עריכה]

במערכות הפעלה המאפשרות ריבוי תהליכונים (Multithreading) בתהליך אחד, קיימת גישה חופשית של כל התהליכונים בתהליך לכל המידע במרחב הכתובות של אותו תהליך. מצב זה מאפשר למתכנת מערכות תוכנה המבוססות על ריבוי תהליכונים שיתוף מידע פשוט ומהיר בין התהליכונים, אך ניהול של נתונים משותפים אלה עשוי לסבך את כתיבת התוכנית, ולהגדיל את הסיכוי לתקלות בתוכנה. דוגמה למצבים כאלה היא תחרות (Race conditions) בין התהליכונים העשויה לגרום לדריסת מידע לפרקים. כדי למנוע תופעות אלו, מספקות מערכות ההפעלה ושפות התכנות כלי סנכרון כדוגמת נעילה, סמפור וקטע קריטי. כלים אלו מאפשרים לתאם את הגישה למידע על ידי התהליכונים, אך יוצרים בתורם באגים פוטנציאליים נוספים כדוגמת קיפאון (Deadlock) שבו שני תהליכונים נועלים כל אחד משאבים שהשני ממתין להם וכך לא מתקדמים לעולם, או הרעבה - כאשר אחד התהליכים הרצים לעולם לא מקבל את המשאבים הנחוצים לו.

מימושים[עריכת קוד מקור | עריכה]

ניתן לממש תהליכונים ברמת הליבה (Kernel-level) או ברמת המשתמש (User-level):

  • ברמת הליבה - צורה זו היא צורת המימוש הפשוטה ביותר, ובה כל תהליכון הוא ישות שמערכת ההפעלה יכולה לזמן. ב-Win32 אפשרות זו נתמכה מההתחלה. בלינוקס ספריית glibc מממשת זאת (על ידי NPTL או LinuxThreads לפני כן).
  • ברמת המשתמש - כל התהליכונים של תהליך הם ישות אחת בעיני מערכת ההפעלה, שכלל אינה מודעת אליהם. בגישה זו אין צורך בתמיכה של מערכת ההפעלה. לגישה זו יתרון מבחינת הזמן המבוזבז על החלפת הקשר, אך לא ניתן ליהנות מהאצת חומרה (ריבוי מעבדים או מעבדים שתומכים בריבוי תהליכונים - Multithreading).