THREADS

yair24

Member
THREADS

שלום, אני מנסה ללמוד ולהבין מה זה THREADS איך משתמשים איתם למה צריך אותם מישהו יכול להסביר? יאיר
 

vinney

Well-known member
תשתמש בהם לאט ובזהירות

אתה זוכר איך ניפנף הילל הזקן את זה שבא לשאול אותו את משמעות היהדות על רגל אחת? תשאל שאלות ספציפיות ותקבל תשובות, בשמחה ובששון.
 

DadleFish

New member
threads לא פותרים בעיות,

רק יוצרים אותן
וביתר רצינות, threads מאפשרים לך לתכנת בצורה יותר טבעית. אם יש לך אפליקציה שצריכה לעשות מספר משימות במקביל, אתה יכול לעשות את זה - לנהל את זה - בעצמך, ואתה יכול לתת למערכת ההפעלה לעשות switch-ים בין מספר תהליכונים שרצים "במקביל" (מובן שלא באמת במקביל, כי יש CPU אחד על המערכת). למשל, נגיד שאתה כותב שרת WEB, שעונה לפניות של HTTP. יש לך כמה משימות בשרת. לדוגמה: 1. להקשיב ל-connections חדשים שנכנסים לשרת 2. לתחזק connections קיימים 3. לבצע קוד server side (כמו דפי PHP/JSP/ASP) וכו'. אתה יכול לעשות לולאה מרכזית בתוכנה שלך, שבכל פעם תבדוק אם יש connections חדשים, מה צריך לעשות עם הישנים, ואיזה קוד server side צריך לבצע כרגע. הבעיה היא שכשתעשה את אחד הדברים הללו, לא תוכל לעשות משהו אחר. למשל, אם ה-server side code שאתה מריץ לוקח 5 שניות, לא תוכל לעשות דברים אחרים בזמן הזה - כמו לקבל פניות חדשות. זו הבעיה בקוד ליניארי. עכשיו, כדי לפתור את הבעיה הזו, עליך לפצל את ביצוע ה-server side code לחלקים בגודל שתקבע בעצמך - למשל, 10ms - ואז להפסיק את העבודה ולנסות לעשות דברים אחרים. זו בעיה ממש לא פשוטה, ומתכון בטוח לצרות. כאן נכנסים thread-ים. אתה מחלק את האפליקציה כך ש-thread אחד מטפל ב-connections נכנסים, thread אחר מטפל בקוד server side, וכו'. זה פוטר אותך מטיפול בעצמך בכל הניהול המסובך של העסק, אבל מציב אתגרים חדשים. למשל, נגיד שיש לך רשימה כלשהי של אובייקטים, ושני thread-ים שונים מנסים לגשת אליה בו זמנית. זה עלול ליצור בלאגן גדול ברשימה, ולכן אתה צריך להכניס סינכרוניזציה בין ה-threads השונים, ולהגן על משאבים משותפים. בקיצור, תכנות multithreaded הוא לא פשוט ויש בו הרבה בעיות פוטנציאליות, אבל הוא מפשט מאוד את מבנה התוכנה ומאפשר להבין אותה טוב יותר.
 

yair24

Member
סינכרוניזציה בין THREADS

כאן בעצם נכנס כל העניין של הקטע הקריטי וסמפורים? יש לי עוד שאלה ספציפית לגבי התוכנה שכתבתי מקודם: אם אני מפעיל את הפונקציה של חישוב המספר הראשוני בתוך THREAD אז כמה THREADS רצים יש לי? 1 או 2? כי הבנתי שהתוכנית עצמה מהווה THREAD אחד אז החישוב של המספר הוא THREAD שני? יאיר
 

yair24

Member
רעיון לתוכנית

יש לי רעיון לנסות תוכנית עם כמה THREADS אני אשמח אם תגידו לי אם הרעיון הוא ישים ונכון לתירגול: אני בונה טופס עם 10 תיבות טקסט ושני כפתורים PUT וGET. לחיצה על PUT מריצה פונקציה בTHREAD הפונקציה מייצרת מספר ושמה אותו בתיבת הטקסט הראשונה שקיימת ומסמנת FLAG שאומר שהתיבה תפוסה לחיצה שוב על הכפתור שוב פעם מייצרת מספר ומכניסה אותו לתיבה הבאה (הפונקציה שתייצר את המספר תעשה את זה בצורה שזה ייקח לה הרבה זמן לייצר את המספר) לחיצה על הכפתור GET פשוט מוחקת את המספר מהתיבה האחרונה שהיתה. וככה זה מן בעית יצרן צרכן כזאת שעובדת עם THREADS... זאת תוכנית טובה לצורך תירגול THREADS? או שפספסתי משהו?
 

annefan

New member
שמאי

לא הלל. הלל אמר לו "מה ששנוי עליך לחברך לא תעשה".
 

gmorph

New member
באופן כללי

זהו מנגנון, המאפשר להריץ תוכניות לכאורה במקביל אפילו על מעבד אחד. למה זה טוב? את זה אני אשאיר לך...פרוסס הוא תהליך המכיל בתוכו מספר THREADS, אחד או יותר. ככה אתה יכול להריץ תהליכים שונים במקביל, ויותר מזה, גם בתוך אותה תוכנית אפשר להריץ חלקים מקבילים.
 

yair24

Member
אוקי

בזמנו כשלמדתי MFC נתנו לנו לעשות תוכנית שמממשת אלגוריתם לחישוב המספר הראשוני הגדול ביותר עד מספר מסוים, כלומר יש לי טופס שיש בו שני תיבות טקסט וכפתור, אני מכניס מספר נגיד 100000 לתוך אחת התיבות ולוחץ על הכפתור, ואז התוכנית מחשבת את המספר הגדול ביותר הראשוני עד למספר שהכנסתי, ומציגה אותו בתיבה השניה. אם הייתי שם מספר גדול אז החישוב הזה היה לוקח כמה שניות טובות, והיה תוקע את החלון עד שהוא היהי נגמר. אז את הפונקציה שמחשבת את המספר הפעלנו בTHREAD. עכשיו אני לא זוכר מה זה עשה... נדמה לי שעשינו כפתור וראינו שכשהפונקציה רצה כTHREAD אז אפשר ללחוץ על הכפתור וכשהפונקיה לא רצה כTHREAD אי אפשר ללחוץ עליו כי התוכנית "עסוקה" בחישוב. אני מחפש דוגמאות לתוכניות פשוטות שמשתמשות בTHREADS בשביל לתרגל את העניין הזה. אם יש למישהו שלומד את זה או שלמד את זה רעיונות והוא זוכר אני אשמח לקבל (הכוונה את הדרישה של התוכנית לא את המימוש). יאיר
 

DadleFish

New member
זה לא מסובך,

זה בדיוק כמו שתיארת את זה - אם אתה לא עושה את החישוב ב-thread נפרד, התוכנית כולה (שזה למעשה ה-GUI) תהיה תקועה.
 

yair24

Member
עוד שאלות

אני רואה שאת הפונקציה שנכנסת לTHREAD מגדירים תמיד בצורה כזאת:
UINT FUNCNAME(LPVOID PAVAR)​
בתוכנית דוגמא שלי מה שעשו שם זה יצרו STRUCT שהכיל שני שדות ונראה ככה:
typedef struct { HWND hwnd; long big; }BIGWND;​
HWND זה הHANDLE לWINDOW תמיד צריך אותו נכון? המשתנה השני BIG זה איזשהו INTEGER שמקבל ערך של משתנה ששיך למחלקה של הטופס שהריץ את הTHREAD פשוט הTHREAD היה צריך להשתמש בו אז אנ ימניח שזאת הדרך למעשה להעביר פרמטרים לTHREAD? יש דרכים אחרות להעביר את הפרמטר? או שזאת הדרך הנכונה? יאיר
 

vinney

Well-known member
לא ממש הבנתי את הסיפור

בגדול THREAD בחלונות מקבל כפרמטר מצביע רחוק (LPVOID), שיכול להצביע על מה שאתה רק רוצה, ובעזרת CASTING פשוט אתה ניגש לנתונים שהמצביע מצביע אליהם. זה יכול להיות STRUCT, מערך, קבוע, אין שום הבדל. מה זה בדיוק - תלוי בTHREAD ומה הוא עושה.
 
אמשול לך משל

(גנוב מהספר על פרל) כל העניין נולד מהצורך בטיפול בדברים במקביל כפי שהדגימו קודם. העניין הוא איך לבצע את זה. האם נריץ תוכנית לכל משימה אן שבתוך תוכנית אחת נריץ כמה thread-ים? נניח יש לנו מטבח ובו כמה שפים שעובדים יחד על תפריט מסובך. גישה אחת היא לתת לכל שף מטבח פרטי משלו עם כל הכלים והאספקה. התפריט יחולק למשימות ומעברים של תבשילי ביניים יועברו ממטבח למטבח. הגישה הזאת עובדת היטב כי כל שף לא מפריע במשימה לשפים אחרים. שיטה אחרת היא לחלק את המשימה לתת-משימות אבל לתת לכל השפים לעבוד במטבח אחד ושיסתדרו ביניהם. למשל מי עובד על המיקסר ומי עכשיו צריך שק תפוחי אדמה לעצמו. זה עלול להיות מבולגן מדי וצריך מישהו שיארגן את העניינים. המודל הראשון הוא המודל התהליכי. לכל משימה נקצה תהליך נפרד. מערכת ההפעלה תדאג לכל המשאבים עבור אותו תהליך. אף תהליך (=תכנית) לא תדרוס ותקלקל לתכנית אחרת. המודל השני הוא המודל של thread-ים. כולם עובדים יחד במקביל אבל לכולם יש משאבים משותפים של אותו תהליך. המודל התהליכי יותר פשוט אבל המודל של threads יותר חסכני במשאבים ולעיתים יותר טבעי. לשניהם מקום ומשתמשים בהם ע"פ הצורך.
 
למעלה