
הטקסט המלא של הדקות הראשונות בהרצאה «Threads - חלק 2» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
תרד יכול להיות מוגדר או כ-foreground או כ-background. כאשר אנחנו פותחים אובייקט Thread הוא אוטומטית מוגדר כ-foreground.
ואנחנו צריכים להבין מה ההבדל בין הגדרת התרד כ-foreground Thread לבין הגדרת התרד כ-Background Thread.
כל מה שזה אומר זה שכאשר התוכנית תסתיים, האם תרד ימות אוטומטית, כן או לא. אם הטרד מוגדר כ-foreground זה אומר שכאשר התוכנית הראשית תסתיים, כלומר המיין בייסיקלי, אז הוא ימתין, התוכנית תמתין ולא תסתיים עד שכל הטרדים שמוגדרים כ-foreground יסתיימו.
אם הטרד מוגדר כ-background התוכנית לא תמתין לו וברגע שהתוכנית תסתיים, זה אומר כשלא יהיו יותר foreground threads, אוטומטית ה-Background Threads ימותו.
זה אומר, תוכנית ממשיכה להתקיים כל עוד יש לה 4-Ground Threads. ברגע שאין לה תוכנית יותר 4-Ground Threads, היא מסתיימת והורגת איתה את כל ה-Background Threads.
בואו נוכיח את זה. לצורך ההוכחה אני אפטר רגע מה-readline ומה-cancelation ואני רוצה כרגע להדפיס כאן איזושהי הודעה end of main רק בכדי לראות שה-end of main מתבצעת וכרגע יש לי פה שני threadים אחד רץ 10 פעמים השני רץ 15 פעמים אנחנו רואים ששלחנו פה את ה-15 ורק כששניהם
מסתיימים התוכנית תסתיים. זאת אומרת, בעצם אנחנו אמורים להמתין עד ש-T2 עם ה-15 הדפסות שלו יסתיים ואז התוכנית באמת תסתיים. אנחנו אבל נראה את ה-End of Main מיידית.
בואו נריץ את זה. על ההתחלה אנחנו כבר רואים את ה-End of Main, שימו לב שגם T1 וגם T2 הספיקו להדפיס איזה משהו על המסך לפני ש... הקונסול רייט ליין של האנד אוף מיין התבצע אבל אנחנו רואים שכל ההדפסות הסתיימו ואז יש לנו את הפרס אני קיטו קונטיניו שזה אומר שבעצם התוכנית עצמה הסתיימה.
אם נחשוב רגע כמה טרדים באמת יש כאן אנחנו נראה שאוטומטית אנחנו רואים פה שלושה טרדים טרד אחד זה בכלל הטרד הראשון שהפעיל לנו את התוכנית. הטרד הזה נקרא The Main Thread.
טרד שנקרא The Main Thread, טרד הראשי, זה הטרד שמריץ את פונקציית ה-Main. וחוץ ממנו אנחנו יצרנו בעצמנו עוד שני טרדים שמריצים כל אחד בהתאמה את פרינט 1 ואת פרינט 2. זאת אומרת שיש לנו פה שלושה טרדים.
עכשיו, מה שקרה כאן זה שהתוכנית עצמה לא הסתיימה, אלא אם כן שני הטרדים שהרצנו יסתיימו. כל מה שאני עושה עכשיו זה אומר כזה דבר. בואו נעשה איזשהו ניסוי מאוד מעניין, בואו ניקח את הטרד הראשון ונשים אותו שירוץ רק שלוש פעמים.
אם אנחנו מריצים את זה, אז הטרד הראשון רץ שלוש פעמים בלבד, אנחנו רואים פה הדפסות של 1, 2 ו-3, כלומר את הספרה האחת אנחנו רואים פעם ראשונה, פעם שנייה, פעם שלישית וזהו זה.
אבל כמובן שהתוכנית חיכתה עד שגם T2 הסתיים, היא גם T1 וגם T2, שתיהם נחשבים foreground threads. כל מה שאני רוצה לעשות עכשיו זה לגשת ל-T2 ולומר is a background true, וזה הופך את ה-thread ל-background thread.
זה אומר שהתוכנית לא תמתין יותר ל-T2. אם אנחנו נריץ את זה, בואו נחשוב רגע לפני שנריץ מה יקרה. התוכנית תתחיל את התהליך הראשון ומיד תתחיל את התהליך השני, שניהם ירוצו ברגע שהתוכנית מסתיימת, כלומר ההרצה של המיין תסתיים, היא תמתין אך ורק ל-Fall Ground Thread, זאת אומרת רק ל-T1.
ברגע ש-T1 תסתיים, אוטומטית המיין באמת יסתיים, התוכנית עצמה תסתיים, ואז הוא יהרוג את כל ה-Background Thread, וזה אומר T2, T2 ימות.
בואו נסתכל על זה. אנחנו מריצים, אנחנו רואים ברגע ש-T1 הסתיים לרוץ את שלושת ההדפסות של הספרה אחת, אוטומטית התוכנית הסתיימה והרגה איתה את T2. אז המקרה השלישי שבו טרד יכול למות זה כאשר הוא הוגדר כ-Background והתוכנית עצמה הסתיימה והרגה אותו.
אף אחד לא קרא לאבורט והפונקציה שלו עדיין לא הסתיימה. אם כך, מתי אנחנו רוצים שתהליך יהיה foreground ומתי אנחנו רוצים שתהליך יהיה Background.
אנחנו רוצים שתהליך יהיה foreground כאשר אם היוזר סוגר את התוכנית עדיין אנחנו רוצים שהתהליך הזה ירוץ ברקע עד שיסתיים. דוגמה, יוזר פותח תוכנית לשליחת מייל, שולח את המייל וסוגר את התוכנית לפני שהמייל יסתיים להישלח.
בגלל ששליחת מייל לוקחת הרבה זמן אנחנו יכולים לפתוח את זה בתהליך נפרד. אז בואו נניח שפתחנו את השליחת המייל בתהליך נפרד, כלומר בטרד נפרד, וברגע שהוא סגר את התוכנית, מיד אחרי שהוא לחץ לשלוח את המייל, יכול להיות שהתוכנית עדיין לא סיימה לשלוח את המייל.
יכול להיות שהיא קוראת איזשהו קובץ בשביל לשלוח את המייל, שאותו היא צריכה לשלוח, יכול להיות שלוקח לה טיפה זמן ליצור קישור לאינטרנט.
אנחנו לא רוצים שבגלל שהיוזר מיד סגר את התוכנית, המייל יבוטל. לכן טרד כזה, שאמור בוא נניח לשלוח מייל או להדפיס משהו למדפסת, אפילו שסגרו כביכול את התוכנית, אנחנו רוצים שהתוכנית לא באמת תיסגר אלא תמתין עד שהטרד מסיים את המטלה שלו.
יכול להיות אפילו שהיוזר לא יראה שום חלום כי הוא סגר את החלונות, אבל עדיין מאחורי הקלעים הטרד ממשיך לעבוד בלי שהיוזר רואה אותו ומסיים את המטלה שלו. זאת דוגמה שבה היינו לוקחים foreground thread.
עדיין לוקחים Background Thread. Background Thread היינו לוקחים כאשר אנחנו לא רוצים שהתהליך ימשיך אם התוכנית מסתיימת. בואו נראה דוגמה. אם יש לנו לדוגמה טופס ורואים על הטופס איזושהי גרפיקה של ציור שזזה על גבי הטופס, אז הפעילות הזאת של הגרפיקה שזזה, בואו ניקח דוגמה של איזושהי שמש שזזה על הטופס מימין לשמאל,
מגיעה לצד השני וחוזרת בחזרה בלי הפסקה. הפעילות הזאת של התזוזה של הציור של השמש לוקח הרבה זמן, לכן הוא חייב להיות בטרד נפרד.
אבל רגע, אם היוזר סגר לי את הטופס ובעצם סוגר את התוכנית, האם אני רוצה להמשיך ולצייר את התמונה של השמש על גבי הטופס? הוא סגר לי את התוכנית, אין לו יותר טופס.
זה מקרה שבו אנחנו לא רוצים שהטרד הזה ימשיך וזה יהיה טרד שהוא background, טרד בכדי שאוטומטית הטרד ימות כאשר כל התוכנית מסתיימת.
אז אלה מספר מקרים שטרד שהופעל הסתיים. יש כמובן את המקרה שאם הייתה חריגה בתוך הפונקציה אז הפונקציה בעצם מה שקורה זה שהתוכנית יוצאת מהפונקציה ואז כמובן גם הטרד מסתיים אבל שימו לב שזה אותו המקרה כמו שפונקציה הסתיימה כי פונקציה יכולה להסתיים גם אם יש חריגה בתוך הפונקציה.
אז בעצם אפשר לראות שיש שלושה מקרים שתהליך הסתיים. או שהפונקציה שהפעיל מסתיימת, או שמישהו קרא לאבורט מבחוץ, או שהוא הוגדר כ-Background והתוכנית הפסיקה ואז הטרד אוטומטית מת.
כמה דברים נוספים שחשוב לדעת בנוגע לטרדים. קודם כל יש לנו איזשהו משתנה כל טרד שאומר האם הטרד חי, כן או לא. בואו נדפיס כאן t1 is alive ונדפיס t2 is alive ונראה שעל ההתחלה אנחנו רואים true וtrue שניהם חיים.
אם היינו מורידים את ה-is background ושמים פה איזשהו console read line נריץ את זה, נמתין ש-t1 יסתיים ונראה שאנחנו מקבלים false וtrue, סולף על T1 כי הוא כבר הסתיים וטרו על T2 כי הוא עדיין רץ.
אז יש לנו את המשתנה Ease Alive שאנחנו דרכו יכולים לדעת האם הטרד פעיל או לא. משתנה נוסף שקיים לנו ברמת הטרד זה Priority. Priority זה אינאם שמציין את הקדימות של הטרד יחסית לטרדים אחרים שקיימים באותו המחשב.
אם אנחנו נשים את הטרד הראשון כ-Priority Lowest ואת הטרד השני כפריוריטי הייסט ונריץ. אז אנחנו רואים