שאלה על threads ועל events

Gardner

New member
שאלה על threads ועל events

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

DadleFish

New member
event....

עשית אותו manual reset או auto reset? למה לא להשתמש ב-critical section או ב-mutex או ב-semaphore, אם אתה ממילא רוצה להמתין?
 

Gardner

New member
אני מנסה פה גם אוטומטי וגם ידני

האוטומטי אמור פשוט לתת לחוט אחד בלבד להתעורר מהאירוע, נכון? אז אני אמור להוריד את כל הקריאות ל ResetEvent, ולתת לו להעיר חוט אחד, ולכבות אותו לבד. ניסיתי גם עם הידני. אני משתמש במיוטקס. הבעיה היא שיש לי שתי שורת: QueueWaitNotEmpty(); WaitForSingleObject(in_queue, INFINITE); הראשונה בודקת שהאירוע של תור לא ריק פועל. השניה בודקת שאין אף אחד בתוך התור (אני לא יכול לשים אותן הפוך, כי זה יתקע את החוט - יחכה שהתור יקבל איבר, אבל ינעל את התור). הבעיה נוצרת כששני חוטים מחכים בשגרה הראשונה, ושלישי מכניס איבר לתור. שניהם מתעוררים ורואים שהתור לא ריק, ושניהם יוצאים. הראשון יעבור את המיוטקס בשגרה השניה, והשני יחכה שם. אבל אחרי שהראשון יצא מהתור, ויוציא ממנו את האיבר שהרגע הכניסו, השני יכנס ישר, כי הוא לא בודק שוב אם התור לא ריק.
 

DadleFish

New member
מה פתאום שניהם מתעוררים?

כשיש לך event שהוא auto reset, רק thread אחד יתעורר. אופציה נוספת היא להשתמש ב-semaphore שיש לו max=1, ולאתחל אותו כאילו הוא תפוס - ואז ה-thread שמכניס יעשה give וה-thread-ים האחרים יעשו take. רק אחד ישתחרר כשיהיה give, והשני ימשיך לחכות על ה-take עד ל-give הבא.
 

Gardner

New member
כשאני שם על אוטומטי

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

Gardner

New member
בנוסף להכל

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

Gardner

New member
הבעיה היא כזאת

שני חוטים מחכים לאירוע queue_is_not_full האירוע מוגדר כאירוע אוטומטי. התהליך הראשי מכניס איבר לתור, ועושה SetEvent(queue_is_not_full) עכשיו, לדעתי רק חוט אחד אמור לצעת מהאירוע, להכנס לתור, ולהוציא ממנו איבר. אבל משום מה קורה ששני החוטים יוצאים מהאירוע, הראשון נכנס לתור, מוציא ממנו איבר. התור עכשיו ריק, אבל האירוע השני לא בודק את זה בכלל. נכנס ותור, ומוציא ג'אנק. יש פה למישהו רעיון למה זה קורה, או איך אני יכול לעשות שזה יעבוד?​
 

gilad_no

New member
מקטע קריטי

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

Gardner

New member
אני לא יודע מה זה מקטע קריטי

ויותר חשוב - אני לא אמור להשתמש בו בתרגיל הזה. אני אמור להשתמש באירועים וחוטים. כל הבעיה היא בהגדרה של האירוע הזה של תור-לא-ריק. אם אני שם אותו על אוטומטי, זה אמור להעיר רק חוט אחד. אבל במקרה הזה פשוט כולם נתקעים ב waitforsingleobject.
 

DadleFish

New member
אז פשוט יש לך באג.

אם אתה רוצה אתה מוזמן לבודד אותו למינימום האפשרי ולהעלות אותו (לא, אל תעלה 700 שורות קוד).
 

Gardner

New member
תודה רבה

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