שיעור 18: Non-blocking I/O ו-epoll
I/O בלוקינג הוא ברירת המחדל — read() ממתין עד שיש נתונים. עם O_NONBLOCK, read() מחזיר מיד עם EAGAIN אם אין נתונים. אבל איך מנהלים אלפי FDs בו-זמנית? epoll פותר בדיוק את זה — event loop שמודיע לנו רק כשFD מוכן, בO(1). ה-Triton Inference Server של NVIDIA משתמש בepoll כדי להגיש אלפי בקשות GPU בו-זמנית.
I/O בלוקינג הוא כמו לעמוד בתור לכרטיס ולחכות שם. non-blocking הוא כמו להגיד לכרטיסן 'תתקשר אלי כשתהיה מוכן'. epoll הוא כמו מוקדן שמנהל אלפי שיחות ומעביר לך רק את אלה שמחכות לתשובתך.
- Non-blocking I/O
- מצב שבו קריאות I/O (read, write, accept) לא חוסמות. אם אין נתונים מוכנים, הן מחזירות -1 עם errno=EAGAIN/EWOULDBLOCK. מופעל עם O_NONBLOCK flag.
- epoll
- ממשק Linux לניטור אירועי I/O על קבוצה גדולה של file descriptors. מורכב מ-epoll_create, epoll_ctl ו-epoll_wait. מחזיר רק FDs מוכנים — O(1) לעומת O(n) של select.
- edge-triggered (ET)
- מצב epoll שבו אירוע מדווח פעם אחת בלבד — כשמצב ה-FD עובר מ-not-ready ל-ready. מצריך קריאה עד EAGAIN בכל פעם. יעיל יותר אבל מורכב יותר.
- level-triggered (LT)
- מצב epoll ברירת מחדל — אירוע מדווח בכל פעם ש-epoll_wait קרוא כאשר ה-FD עדיין ready. פשוט יותר מ-ET אבל יכול לגרום ל-busy-loop אם לא מטפלים כראוי.
- event loop
- דפוס תכנות שבו תוכנית ממתינה לאירועים ומטפלת בהם בזה אחר זה — לולאה אינסופית שקוראת ל-epoll_wait ומפעילה callbacks. ליבה של Node.js, Nginx ו-Triton.