עבור לתוכן

regex בפייתון ו-GIL

Featured Replies

פורסם

היי,

רציתי לשתף אתכם במוזרות שנתקלתי בה בפייתון וכדאי להכיר אותה.

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

בשביל לשחזר את העניין כתבתי Unittest שמנסה לפרסר את אחת מהמחרוזות הבעייתיות באמצעות קטע הקוד הנ"ל. ה-UT פעל באופן הבא: הוא הגדיר thread שמריץ את הקוד הפרסור על המחרוזת. לאחר קריאה ל-start של ה-thread, נקראה הפונקציה join שלו עם timeout מסויים. בסיום ה-timeout נבדק אם ה-thread עדיין חי. אם כן - ה-regex נתקע. אם לא - ה-regex הצליח.

פה קרה דבר מוזר, הקריאה ל-start של ה-thread חסמה את המשך הרצת הפונקציה! למרות שמדובר ב-thread חדש!

חקרתי את העניין וגיליתי (ופה יש צורך להיכנס מעט לקרביים של פייתון):

כידוע, בפייתון אין באמת multithreading - רק thread אחד רץ בכל רגע והדבר מנוהל ע"י ה-GIL.

חלקים גדולים מהליבה של פייתון כתובים ב-C. אותם ה-GIL לא יכול לנהל בעצמו ונהוג לשחרר אותם ידנית ב-C-extension לפני פעולות שדורשות עיבוד כבד ולא מצריכות GIL נעול.

אבל - ה-c-extension של regex בפייתון לא משחרר את ה-GIL. הדבר גורם לכך שברגע שפייתון מנסה לפרסר regex, הוא לעולם לא יפסיק באמצע ולא יתבצע context-switching ל-thread אחר.

כלומר, בעיה בפרסור regex ב-thread אחד יגרום לכל תוכנית הפייתון להיתקע.

פורסם

זה באמת משהו שחשוב לדעת כשמתעסקים עם הספריה re.

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

בכל מקרה אני אישית לא ניסיתי אותה.

(עוד קצת דיון על הנושא: http://www.benfrederickson.com/2013/04/09/python-catastrophic-regular-expressions-and-the-gil.html)

  • 3 שבועות מאוחר יותר...
פורסם

תודה על השיתוף! בעיה ששווה לשים לב אליה.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים