
Sleep(100), כלומר עשירית השנייה, ובכך מודפסים כעשרה מספרים בשנייה.new, להעביר את המצביע אליו, ולהוסיף בנאי שמאתחל את השדות.הטקסט המלא של הדקות הראשונות בהרצאה «יצירת תהליכון - Thread» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
טוב, בואו היום אנחנו נלמד על שרדים, על תהליכוניים, נפתח את הוויז'ואל סטודיו, קריאייט פרוג'קט, לא ב-C-Sharp, האתגר היום הוא ב-C או ב-C++, 32, 32 וזה יהיה קריאייט שרד סאמפל 01, יצירה של שרד ונגיד לו אוקיי.
אפליקיישן סטינג, MT כמובן, סליחה, בלי pre-compile ו-empty, נקי, נקי, נקי, קונסול, נקי וזהו ונגיד לו finish ואת זה אפשר לסגור, עכבר ימני ו-add new item ו-c++ זה ייקרא main רוצה בשפת c או ב-c++ לא משנה אז אם אני לא אומר כלום אז הוא יפסיק סיומת cpp והתוכנית הזאת תהיה ב-c++ אז בואו נגיד לו void,
אין, פתח סגור סוגריים מסובסלים, פתח סגור סוגריים רגילים, או הפוך, סוגריים רגילים, סוגריים מסובסלים. בואו נריץ, נראה שמשהו מינימלי עובד, נחכה לו, יפה.
זה עובד, את זה אני אקטין, את זה אני אקטין, שיהיה ככה, עכבר ימני וproperties, לא עולה, כן, זה בעיה, זה בעיה, אז בואו נגיד לו get char, פתח סגור ובצע הוא לא מוכן והרת מחדש ו-no אז בואו נראה הוא לא מכיר את get char יפה מאוד אז איפה get char נמצאת אני חושב שהיא ב-stdio.h בואו נגיד לו צולמית include stdio.h והרת יפה נקטין אותו עכבר ימני וproperties
מצוין ואוקיי וזה ואוקיי אז יהיה קטן. יפה מאוד, בואו נגיד לו פה enter, אז הוא נסגר מצוין.
טוב, אז מה שאנחנו רוצים זה לכתוב תוכנית שיוצרת Thread, וב-thread נגיד שהיא מדפיסה למסך הדפסה. יפה.
התוכנית הראשית תחכה ל-enter והתוכנית המשנית ה-thread רק ידפיס למסך בתור התחלה. אז בואו אולי נתחיל מזה שנעשה פה לולאה. פור אינט איי שווה ל... שווה לאפס, איי קטן ממגיד איזה מספר, 10, 1, 2, 3, 1, 2, 3, 10 מיליון, ואיי פלוס פלוס ו...
עכשיו, אם לולאה כזו אינטנסיבית תהיה לנו בעיה כי זה יקפיץ ה-CPU מאוד גבוה וזה יהרוס לי את ההקלטה. זאת אומרת, האודיו, שזה מה שיותר חשוב לי, ידפק לי.
למנת שכן אנחנו נקרא פה סליפ, סליפ משום מה הוא אומר שהוא לא מכיר אותה קונטרול רווח, לא יודע, קונטרול שיפט v בואו נראה, סליפ אידנטיפה not found, זאת אומרת איפה סליפ נמצא?
אז f1, נחכה ל msdn שיעלה לו אז הנה הוא מתחיל לעלות, יפה, סליפ, השאלה אם זו הסליפ הנכונה בואו נגיד, זה נראה לי שזה הסליפ הנכונה נגיד לו sink-slip שנמצא בפרוסס נפרד פונקצ'יינס בסיסטמפ סרוויסס אז דיקייט אוגומנטיישן זה נראה שזה בסדר בווין 32 ווין 32 זה בסדר גמור
אז זאתי סליפה טובה יפה אז איפה נמצאת ההצהרה שלה זה אומר שההצהרה נמצאת או, header בווינדבייס, זאת אומרת declared in winbase.h אבל include את windows.h למרות שההצהרה נמצאת בווינדבייס.h אתה אבל תוסיף את windows.h כי זה מה שכדאי לעשות, אז בואו נשכפל את השורה
הזו וזה יהיה windows.h ו-ctrl shift רווח, ctrl shift s, ctrl shift רווח, ctrl רווח, הוא עדיין טרנד שהוא לא מכיר אבל ctrl shift b, הוא עדיין לא מכיר, אה, סעיף 5 של does not take 0 ארגומנטים, יפה מאוד, אנחנו נעשה פה סליף של עשירית השנייה, אז 10 פעמים בשנייה אנחנו נשען, וכך תעבור לשנייה אחת, מה שאמור
להוריד את ה-CPU די נמוך, יפה, אז זה יהיה, זה מה שאנחנו הולכים לעשות, בואו נקטין את ה-MZN, בואו נריץ, אה, אבל לא עשינו שום דבר בלולה, אז רגע, אז בואו נעצור, בואו נסגור את זה, לא תהיה לנו שום אינדיקציה לא תהיה לנו שום אינדיקציה שהוא עושה משהו
אז בואו נדפיס printf וגרשיים ונדפיס את i ואחוז d, יפה ובואו נריט, נראה איך זה נראה אוקיי הוא מדפיס, הוא מדפיס לרוחב, ה-cpu די נמוך, קשה לראות שהוא מדפיס כי הוא לא עובר שורה, בואו נגיד לו לעבור שורה בקסלשן והרס יפה cpu די נמוך הוא סופר די לאט וזה בסדר גמור יפה אז יש לנו לולה אחת שזה
מה שהיא עושה היא פשוט מדפיסה אבל הייתי רוצה בוא נגיד שהייתי רוצה שיהיו לנו שתי לולות כאלה במקביל אחת מדפיסה את הלולה הזו והשנייה מדפיסה נגיד איזה לולה אחרת או בוא נגיד זה כן הייתי בקיצור הייתי רוצה שני x rel'ים שיעשו את אותה פעולה במקביל אז איך עושים את זה?
אז מה שאנחנו נעשה, פה אנחנו נקרא לפונקציה, בואו את זה נסגור, נקרא לפונקציה create thread, ובואו נראה מה הסיפור שלה. create thread, דבר ראשון מחזירה handle.
אז נגדיר handle h, רגע, קודם כל הוא, אוח, כיבדתי אותו, עוד פעם. handle h thread שווה ל, יפה. זה ה-thread שאנחנו ניצור שמור ורווח security בלי security stack size בלי זאת אומרת הוא כבר יבחר את ה-stack size את גודל המחסנית ה-default אני חושב שזה 1 מגה בייט אז אם אני אומר לו 0 זה יהיה 1 מגה בייט וה-start
address הכתובת של הפונקציה איפה אנחנו מתחילים אז הוא אומר פה שזה צריך להיות מסוג long pointer ל-thread start routine אוקיי אז בואו נראה איך זה אמור לראות פליק על זה ו-F12 אפשר גם ללכת ל-MSDN ולראות ב-MSDN איך זה אמור לראות אבל אפשר גם ללכת לפה ו-F12 ולראות איך פה זה אמור לראות זה
אמור לראות כך אז הוא אומר שכאן אגב הוא עושה פה טייב דף למי שעובד בשפת C שהפוינטר לצרד סטארט רוטין זה גם LP אז לא קשור למי שעובד בשפת C זה פשוט מוסיף פה L לא חשוב מה שהוא אומר פה זה שהוא מגדיר את פוינטר לפרק סארט רוטין את האידנטיפה את המזהה הזה הוא מגדיר שזה מצביע לפונקציה שהיא מסוג win api win api f12 זה בסך הכל std
call יפה הפונקציה מחזירה דאבל וורד ומקבלת כפרמטר void lp void f12 זה בסך הכל void far כוכבית מה זה far f12 far זה כלום יפה זאת אומרת void כוכבית, עוד פעם F12 זה בעצם LP void, זה בסך הכל void כוכבית.
יפה מאוד, אז void כוכבית זה הפרמטר שהיא מקבלת. מה זה עוד פעם? אז היא double word, מחזירה את double word, היא מסוג winAPI והיא מקבלת void כוכבית.
אז בואו נגדיר אותה, אז נשים אותה פה למעלה כדי שלא נצטרך גם להצהיר עליה. אז double word, קונטרול רווח enter, זה יהיה ה-thread pro, והיא מקבלת void כוכבית, אני אוהב לקרוא לזה state, את המצב.
יפה. ובואו נשים פה breakpoint, ובואו, וקונטרול שיפט רווח, נשים פה את thread proc control רווח, והפרמטר כרגע יהיה 0, זאת אומרת מה שיועבר ל-state זה 0.
מה עוד אנחנו יכולים להעביר ל-create thread? Creation Flags, תכף נראה אם צריך או לא צריך בינתיים להעביר 0 וLong Pointer ל-thread ID, מה המזהה של ה-thread?
אני חושב שאם אני אעביר לו 0, הוא יסבול את זה והוא יתמודד עם העובדה שאני בעצם לא צריך את המזהה הזה. אין לי מה לעשות איתו. גם את ה-Handle של ה-thread אני לא כל כך צריך, אבל אני אקבל אותו בכל מקרה.
יפה. ובואו נראה מה עכשיו הולך לקרות. אז בואו נריץ את התוכנית. No, מה הבעיה? כן, איזה סגנון קיבל ברמת עזרי?
From viewer to LP thread start routine. יפה, כי שכחנו, כן, cdcler. כרגע זה cdcler, והוא אומר שזה צריך להיות lp thread start routine שהוא win api, שהוא בעצם, אני הולך לתת לו win api, ה-f12 זה בעצם std call, נכון? זה מה שהוא אמר על עצמו.
אני win api, אני std call. אני יכול להגיד פה win api, אבל אני תמיד מעדיף להגיד std call, יפה, ובצע, הוא לא אוהב את זה. זאת אומרת, פרוגמנס ריטורן ווליון, אז בואו נגיד לו לעת עתה ריטורן 0, ובצע, נחכה לו, יפה, וצור את ה־thread, והתחל, עכשיו ברור שעשינו סליפ, אז ה־thread התחיל לרוץ.
עכשיו אנחנו ב־thread, עושים ריטורן 0, ומה? הגענו לאנשהו, אני יכול להמשיך לרוץ כאן הוא קבע עכשיו לאיזה פונקציה וקורא לעוד פונקציה בקיצור, אם נגיד לו תמשיך לרוץ, קפץ לי העכבר אם אני אגיד לו תמשיך לרוץ, אז הוא בפרינטף טוב, אז בואו נראה איפה הוא נמצא, כרגע הוא פה, בואו נסגור את זה
אז הוא מראה לנו שהוא בפרינטף, בואו ניתן לו לרוץ יפה, אז הוא מצפיץ, והפלט שלנו בינתיים כבר מת, יפה בואו ניקח את הקוד הזה ונשכפל אותו לכאן, יפה, וכאן אנחנו נגיד שאת זה מדפיס ה-thread, או אפילו נכתוב פה a.2, התכוונתי ל-a קטנה, על זה אנחנו נדפיס a,
וכאן אנחנו נגיד שזה b. ובואו נוריד מחדש, יפה, אז מה אנחנו רואים פה? בואו נעצור את זה, נחזור אחורה, אנחנו רואים ש-a התפיס, b התפיס, a התפיס, b, a, b, a, b. למה הוא מאוד ברור באותו a, b, a, b?
כי כל אחד עושה סליפ. ברגע שמישהו רוצה סליפ, אז הוא מאפשר למישהו אחר לרוץ. אז לכן זה די בטוח שתמיד זה יהיה a, b, a, b, כל פעם אחד אחר.
יפה. כמובן שאני יכול גם להגיד לו ctrl+cv ולייצר עוד סרד. אני לא צריך כל כך את ההנדל הזה, נעזוב את ההנדל כרגע אז יהיה לנו create thread ומה שאני רוצה זה ש-core thread ידפיס משהו אחר אז בואו ב-state נעביר לו את האות ב-LP פרמטר פה נעביר לו אתה תדפיס a ואילו אתה תדפיס b והתוכנית עצמה מצידי לא תדפיס
כלום היא תחכה ל-enter כדי להסתיים יפה אז ב-state אנחנו נקבל את האות אז char t שווה ל-casting ל-char של state. הבעיה שהוא מעביר void כוכבית, זאת אומרת, מבחינתו פה זה אמור להיות void כוכבית,