Threads
Process - מגדיר את מרחב הכתובות, טקסט, משאבים וכו׳
Threads- מגדיר חלק מסויים של הרצה בתוך process (PC,Stack,Registers).
כמה דגשים חשובים על threads:
- threads תמיד משוייכים ל process.
- לprocess יכול להיות מספר threads שיכולים לתקשר בינהם ללא system calls, message passing או shared memory.

שימוש ב threads יעיל יותר ומאפשר סינכרוניזצייה טובה יותר בגלל שהם חולקים בינהם code, data ,files .
היתרונות של threads:
- responsiveness: התוכנית יכולה לרוץ גם כאשר חלקים ממה חוסמים או מבצעים פעולה מאוד ארוכה.ֿ
- resource sharing: תהליכונים חולקים את המידע של התהליך שיצר אותם.
- economy: להחליף בין threads זאת פעולה הרבה יותר קלה מאפשר לבצע context switch בין processes.
- scalability: במערכת multiprocessors יכולים מספר threads לרוץ על מספר מעבדים בו זמנית ולהריץ חלקים שונים מאותה התוכנית.
אתגרים:
- חלוקת משימות בין threads בצורה נקיה ומקבילית.
- חלוקה מאוזנת בין המשימות מבחינת ניצולת מעבד. כלומר שאם thread אחד מבצע משימה והשני ממתין לו אין סיבה שהוא יקבל זמן מעבד בעצמו.
- שמירת הdata באופן כזה שיתמול בעדכונים והרצה מקביליים.
- קושי ב debugging.
Kernel Threads
- זה thread שמערכת ההפעלה מכירה.
- החלפה בין kernel threads מצריך context switch אם כי הוא קל יותר לביצע מהcontext switch בין תהליכים עצמם (צריך להחליך רקק ערכי registers, PC ו stack pointer).
- הkernel מתזמן בין הthreads הללו (בנוסף לתזמון בין processes).
היתרון המשמעותי של kernel threads הוא בעובדה שהוא מהווה סוג של תהליך, כלומר מערכת ההפעלה מתזמנת בינהם באותו אופן שבוא היא מתזמנת תהליכים ולכן יכולה להיות מקביליות. המחיר הוא over head של context switch.
User Threads
threads שנוצרים ברמת ספרייה כלשהי. הניהול שלהם הוא בעצם ההחלטה מעל איזה kernel thread ישבו ה user threads של אותה תוכנית.
מערכת ההפעלה לא מכירה את הuser threads שנוצרים ברמת הספרייה, כלומר מבחינת מערכת ההפעלה התהליך שמריץ תוכנית שלנו הוא single thread.

יתרונות:
- אין context switch כאשר מחליפים בין threads.
- תזמון של user threads הוא יותר גמיש:
- ניתן לתזמן בין threads מסויימים במודול כלשהו בקוד שלי באופן מסויים ובמודול אחר לתזמן אותם אחרת.
- כל process יכול לנהל את הthreads שלו אחרת ועם ספרייה אחרת.
- thread יכול לוותר על הריצה שלו ולהעביר אותה לthread אחר באמצעות
yield.
- אין overhead ביצירה כלומר אין צורך בsystem call כדי לאתחל user thread.
- מהירים יותר מ kernel threads.
- יכולים להתקיים בלי תלות במערכת ההפעלה.
חסרונות:
- אין מקביליות אמיתית שכן מערכת ההפעלה לא מכירה אותם.
- לא יכול לקבל החלטות תזמון שתלויות ב user level threads למשל הוא יכול להריץ תהליך שכל ה user threads שלו הם idle. או להעביר process למצב של waiting כי user thread אחד שלו מבצע I/O. הוא מתזמן processes ללא תלות במספר ה user threads שלהם.
Threading Models
הפתרון לבעיות הנ״ל הוא בעצם שיוך של הuser threads ל kernel threads (זה קוד שהספרייה מבצעת באתחול). בשיטה זאת הספרייה יכולה להגדיר כיצד היא רוצה שהuser threads יתזומנו על ידי מערכת ההפעלה. מבנה הנתונים שמאפשר את זה נקרא Lightweight process (LWP)

Many to One:
מספר user threads ממופים ל kernel thread אחד. כלומר, לכל תהליך יש kernel thread אחד והספרייה המנהלת תחליט בכל רגע נתון מי ה user thread שירוץ ברגע שה kernel thread יקבל זמן מעבד. הניהול הוא יעיל אבל יש חסרון משמעותי שכן לכל תהליך יש kernel thread יחיד ואנחנו מעבדים את היכולת ל paralism של התהליך בגלל זה. כמו כן עדיין יש השבתה של כל התהליך ברגע ש thread אחד נכנס ל I/O
One to One:
לכל user thread מוצמד kernel thread ייחודי לו.
היתרון הגדול הוא שנוכל לקבל מקביליות אבל במחיר של over head כי מייצרים המון kernel thread עבור מערכת multithreaded.
Many to Many:
לכל תהליך יש pool של kernel threads והתהליך יכול להשתמש בהם בהתאם.
Two-Level:
שילוב של MM ו OO כך שנוכל להגן עבור user threads שעושים פעולות חשובות מפני יציאה לI/O של threads אחרים.