דבר אחד שמצאתי שימושי במספר מכונות הוא מתג מחסנית פשוט. למעשה לא כתבתי אחד ל- PIC, אך הייתי מצפה שהגישה תפעל בסדר גמור ב- PIC18 אם שני / כל הנושאים משתמשים בסך הכל ברמות מחסנית של 31 או פחות. ב- 8051, השגרה העיקרית היא:
_taskswitch: xch a, SP xch a, _altSP xch a, SP ret
ב- PIC, אני שוכח את שם מצביע הערימה , אבל השגרה תהיה משהו כמו:
_taskswitch: movlb _altSP >> 8 movf _altSP, w, b movff _STKPTR, altSP movwf _STKPTR, c return
בתחילת לתכנית, התקשר לשגרה task2 () הטוענת את altSP עם כתובת הערימה החלופית (16 כנראה תפעל היטב עבור PIC18Fxx) ומריצה את loop the task2; אסור לחזור לשגרה זו אחרת הדברים ימותו מוות כואב. במקום זאת, היא צריכה להתקשר ל _taskswitch בכל פעם שהיא רוצה להעניק שליטה למשימה הראשית; המשימה הראשית צריכה להתקשר ל _taskswitch בכל פעם שהיא רוצה להיכנע למשימה המשנית. לעיתים קרובות יהיו לאחת שגרות קטנות וחמודות כמו:
חלל עיכוב_ט 1 (val short לא חתום) {do Taskswitch (); בעוד ((קצר חתום) (millisecond_clock - val)> 0xFF00); }
שים לב שלמעבר המשימות אין שום אמצעי לעשות שום 'לחכות למצב'; כל מה שהוא תומך הוא ספינווייט. מצד שני, מתג המשימות מהיר כל כך, שניסיון למתג משימות () בזמן שהמשימה השנייה ממתינה לתפוגת טיימר, יעבור למשימה השנייה, יבדוק את הטיימר ויחזור מהר יותר מאשר מחליף משימות טיפוסי. יקבע כי אין צורך לבצע משימות משימות.
שים לב שלריבוי משימות השיתופיות יש מגבלות מסוימות, אך הוא מונע את הצרכים לנעילה רבה ולקוד אחר הקשור ל- mutex במקרים שבהם מופרשים זמנית ניתן להקים מחדש במהירות.
(עריכה): כמה אזהרות לגבי משתנים אוטומטיים וכאלה:
- אם קוראים לשגרה שמשתמשת בהחלפת משימות משני האשכולות, בדרך כלל יהיה צורך לקמפל שני עותקים של השגרה (אולי על ידי # הכללת אותו קובץ מקור פעמיים, עם הצהרות שונות #define). כל קובץ מקור נתון יכיל קוד לשרשור אחד בלבד, או שהוא יכיל קוד שיורכב פעמיים - פעם אחת לכל שרשור - כך שאוכל להשתמש במקרו כמו "#define delay (x) delay_t1 (x)" או #define delay (x) delay_tx (x) "תלוי באיזה שרשור אני משתמש.
- אני מאמין שמהדריכי PIC שאינם יכולים" לראות "פונקציה שנקראת, מניחים שפונקציה כזו עשויה לאשפה כל דבר רושם מעבד ובכך נמנע מהצורך לשמור רישומים כלשהם בשגרת החלפת המשימות [יתרון נחמד בהשוואה למולטי-טאסקינג מונע]. כל מי ששוקל לעבור על משימות משימות דומות לכל מעבד אחר צריך להיות מודע למוסכמי הרישום שנמצאים בשימוש. לפני מתג משימה והקפצה עליהם היא דרך קלה לטפל בדברים, בהנחה שקיים שטח מחסנית הולם. o>
ריבוי משימות שיתופי אינו מאפשר לחמוק לחלוטין מבעיות נעילה וכאלה, אבל זה באמת מאוד מפשט את העניינים. ב- RTOS מקדימה עם אוסף אשפה דחוס r, למשל, יש צורך לאפשר להצמיד אובייקטים. בעת שימוש במתג שיתופי, אין זה הכרחי בתנאי שהקוד מניח שאובייקטים של GC עשויים לנוע בכל זמן שמתקשרים למשימות (). אספן דחיסה שאינו צריך לדאוג לחפצים מוצמדים יכול להיות פשוט בהרבה מזה שעושה.