לחץ "Enter" למעבר לתוכן

פייתון: ריקוד ג'ק וג'יל

כשה-Threads מתחילים לרקוד בלי GIL

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

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

מה זה אומר, בעצם?

פייתון ו-Threads: שלושים שנים של בדידות

פייתון כבר מזמן אינה שפה שנמצאת בחיתוליה. השפה נולדה לפני כ-35 שנה כפרוייקט של גואידו (חידו) ואן-רוסום, והגרסא הבוגרת שלה, פייתון 3, יצאה כבר בשנת 2008.
היא משמשת כבר שנים לאפליקציות רבות בתחומים שונים ובהצלחה רבה.
אך בנושא אחד, משמעותי, השפה גררה איתה שנים רבות מימוש שקשה לקבל בשפה בוגרת: תמיכה ב-Threads.
המימוש הנפוץ ביותר של פייתון, CPython, לא באמת הסתדר איתם.

תמיכה אמיתית ב-Threads היא מורכבת ודורשת תשומת לב רבה לנושאים כמו Race Conditions ו-Deadlocks. כאשר מנסים לשלב זאת בשפה שמבוססת על אינטרפרטר גמיש ורב יכולות, שיתוף מידע אינטנסיבי בין כלל ישויות המערכת וניהול זכרון עם Garbage Collector, זה עוד הרבה יותר קשה מאשר סתם אפליקציה בעלת גבולות ומבנה מוגדרים.

ללכת בלי, ולהרגיש עם

(לא, זו לא טעות…)

משלבים מוקדמים מאוד, הדרך של פייתון להתגבר על הבעייה היתה קצת מביכה: פשוט לא לאפשר Parallelism אמיתי, גם אם ה-API מאפשר Concurrency. כן, ניתן לייצר כמה Threads באותה תכנית פייתון, ולהריץ אותם בו-זמנית. אך הם לא ירוצו באמת במקביל. גם אם למעבד ישנו מספר רב של ליבות, בכל רגע נתון ירוץ אך ורק Thread אחד של אותה תכנית Python. המנגנון שמנהל את המגבלה הזו נקרא GIL – Global Interpreter Lock. הוא מוודא שבכל רגע נתון, רק הקוד של Thread יחיד ירוץ.

אז למה בכלל לייצר Threads בפייתון? שאלה טובה. אם ה-Threads מבזבזים זמן רב על המתנה ל-IO, למשל, אז למרות ה-GIL, ניתן להשיג שיפור בביצועים, כי כמה Threads יכולים להמתין ל-IO בזמן ש-Thread אחר רץ. ישנן גם ספריות ספציפיות, עתירות חישובים, שרצות ב-Parallelism אמיתי באמצעות מימושים מיוחדים. אבל ככלל, מי שמעוניין להריץ את האינטרפרטר של פייתון במקביל על כמה ליבות, צריך לבצע זאת על Processes שונים.

Free Threading Python: זה מתחיל

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

זו עדיין איננה ברירת המחדל; לטובת הרצה ללא GIL יש להריץ את האינטרפרטר בקונפיגורציה מיוחדת.
זו לא סתם שמרנות – זה נובע מעוצמת השינוי והמחירים שהוא עלול לגבות.

בין היתר:

  • זמן הריצה (של קוד שאינו מנצל את המקביליות) עלול להתארך בעד 10-15 אחוז;
  • המערכת צורכת יותר זכרון (עד כ-20%);
  • מערכות או ספריות שנבנו בהנחת קיומו של ה-GIL עלולות להישבר ולא לתפקד כנדרש.

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

מתי זה יקרה?
נצטרך להמתין להחלטה של הדיקטטור הנאור (לשעבר) ומועצתו.
עד אז, יהיה מעניין לבחון את זה בפעולה.

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *