שקעים חופפים I/O לעומת מצב חסימה/ללא חסימה


סיכום


מאמר זה מסביר את ההפרש בין תכונת ה-I/O החופפת של השקע לבין מצב החסימה או החסימה של השקע.

מידע נוסף


כאשר socket נוצר, כברירת מחדל הוא socket חוסם. באפשרותך להשתמש בפקודה FIONBIO בקריאה של ה-API של הרכיב המקומי, WSAEventSelect או WSAAysncSelect כדי לשנות את מצב ה-socket מחסימה לחסימה. אם לא ניתן להשלים את הקריאה של Winsock באופן מיידי, השיחה נכשלת ו-WSAGetLastError מחזירה שגיאת WSAEIEBLOCK אם מדובר בשקע שאינו חוסם, או בלוקי השיחה עד להשלמת הפעולה אם מדובר בשקע חוסם. תכונת ה-I/O החופפת על-ידי socket שונה ממצב החסימה או החסימה של השקע. למרות שיישום Winsock הנוכחי מחייב תכונת I/O חופפת עבור מצב socket שאינו חוסם, הן עצמאיות ומודל התיכנות שלהן שונה מדי. כדי ליצור שקע עם תכונת ה-I/O החופפת, באפשרותך להשתמש ב-API של socket או ב-API של WSASocket עם הגדרת הדגל WSA_FLAG_OVERLAPPED. אם פעולת I/O חופפת אינה יכולה להשלים מיד, השיחה נכשלת ו-WSAGetLastError או GetLastError לחזור WSA_IO_PENDING או ERROR_IO_PENDING, אשר למעשה זהה להגדיר WSA_IO_PENDING. לקבלת מידע נוסף, עיין במאמר הבא במאגר הידע Microsoft Knowledge Base:
179942 מידע: דרוש WSA_FLAG_OVERLAPPED עבור שקעים שאינם חוסמים
שים לב כי לאחר יצירת socket, אין דרך לשנות את התכונה החופפת של socket. עם זאת, באפשרותך להתקשר ל-API של setsockopt עם SO_OPENTYPE בכל נקודות אחיזה של socket, כולל INVALID_SOCKET כדי לשנות את התכונות החופפת עבור כל השיחות של socket עוקבות באותו הליך משנה. ערך האפשרות SO_OPENTYPE ברירת המחדל הוא 0, המגדיר את התכונה החופפת. כל ערכי האפשרויות שאינם שערכם הופכים את השקע לסינכרוני ולהפוך אותו כך שלא תוכל להשתמש בפונקציית השלמה. על-ידי הגדרת תכונת ה-I/O החופפת של socket, לא משמעות הדבר היא שהשקע יבצע פעולת I/O חופפת. לדוגמה, אם תציין NULL הן עבור פונקציית ההשלמה והן עבור המבנה החופף ב-wsarecv ו-wsasend, או שפשוט תתקשר ל-קבל או שלח פונקציות, הן יושלמו בצורה חוסמת. כדי לוודא שה-I/O מבוצע בצורה חופפת, עליך לספק מבנה חופף בפונקציית ה-I/O שלך, בהתאם לפונקציה בה אתה משתמש.

I/O חופפת

ב-Winsock 1, אתה יוצר שקע חופף באמצעות ה-API של socket, ומשתמש ב-api של קובץ Win32/O, ReadFileEx, בקובץ כלשהו, כאשר אתה מבצע את הפעולות I/O החופפת בנקודת האחיזה של השקע. ב-Winsock 2, אתה יוצר שקע חופף באמצעות WSASocket עם דגל WSA_FLAG_OVERLAPPED, או פשוט באמצעות ה-API של socket. באפשרותך להשתמש בממשקי הapi של הקובץ Win32/O לעיל או ב-Winsock 2 WSASend, WSASendTo, WSARecv ו-WSARecvFrom כדי ליזום פעולת I/O חופפת. אם אתה משתמש באפשרות SO_RCVBUF ו-SO_SNDBUF כדי להגדיר אפס מחסנית TCP ולשלוח את המאגר, אתה בעצם מורה למחסנית ה-TCP לבצע באופן ישיר את הערך I/O באמצעות המאגר המסופק בקריאת ה-I/O שלך. לכן, בנוסף ליתרון שאינו חוסם את ה-I/O של השקע החופף, היתרון השני הוא ביצועים טובים יותר מכיוון שאתה שומר עותק מאגר בין מאגר מחסנית ה-TCP לבין מאגר המשתמשים עבור כל שיחת I/O. אך עליך לוודא שאינך ניגש למאגר המשתמשים לאחר שהוא נשלח לפעולה חופפת ולפני השלמת הפעולה החופפת. כדי לקבוע אם פעולת ה-I/O החופפת הושלמה, באפשרותך להשתמש באחת מהאפשרויות הבאות:
  • באפשרותך לספק נקודת אחיזה לאירוע במבנה חופף שנעשה בו שימוש בקריאת ה-I/O ולהמתין לאיתות בנקודת האחיזה לאירוע.
  • השתמש בgetoverlapsult או ווסגרופלפלפסג כדי לסקר את מצב הפעולה I/O החופפת. ב-Windows NT, באפשרותך לציין NULL כמזהה הייחודי של האירוע במבנה החופף. עם זאת, ב-Windows 95 המבנה החופף צריך להכיל נקודת אחיזה ידנית לאיפוס האירוע. המערכת משתנה ב-Windows 98 ו-Windows המילניום מהדורת (ME) שונה כך שהוא יתנהג כמו Windows NT והוא יכול גם לסקור את מצב ההשלמה עם ידית האירוע NULL במבנה החופף.
  • השתמש בקובץ ReadFileEx, כיצד להשתמש ב-WSARecv, בפונקציה Wsarecv, Wסאססוף, או Wsarecv ולבחור לספק פונקצית השלמה שתיקרא כאשר פעולת הפלט/O החופפת הושלמה. אם אתה משתמש בגישה לפונקצית ההשלמה, בשלב מסוים לאחר שהנפיקה את פעולת הI/O החופפת עליך להנפיק פונקצית המתנה של Win32 או גירסת WSA של המתנה כדי להמתין לנקודת אחיזה שאינה מאותת לשים את הליך המשנה הנוכחי שלך במצב המתנה של ההתראות. כאשר פעולת ה-I/O החופפת משלימה, פונקציית ההשלמה שלך נקראת, פונקציית ההמתנה שלך הולכת להחזיר את WAIT_IO_COMPLETION, והליך ההמתנה שלך להמתין מתעורר.
  • השתמש במצב Getתורים ושייך לשקע, יחד עם ערכת התכונות I/O החופפת, עם יציאת השלמה של Windows NT I/O (IOCP). באמצעות IOCP, אין צורך לספק פונקציית השלמה, להמתין למזהה הייחודי של האירוע כדי לאותת או לסקר את מצב הפעולה החופפת. לאחר יצירת ה-IOCP והוספת נקודת האחיזה לשקע החופף ל-IOCP, באפשרותך להתחיל את הפעולה החופפת באמצעות כל אחד מממשקי ה-Api של I/O המוזכרים לעיל (למעט recv, recvfrom, שליחה או הוספה). באפשרותך לחסום את בלוק הליך המשנה של העובד שלך ב-API של Getתורים ממתין למנת השלמה של I/O. כאשר משלים פלט/O חופף, מנת השלמה של I/O מגיעה למצב IOCP והפונקציה Getstatus. IOCP היא התמיכה של מערכת ההפעלה Windows NT לכתיבת שרת תפוקה גבוהה ומדרגי באמצעות שרשור פשוט מאוד וקוד חסימה בפעולות I/O שנחברו. לפיכך, יכול להיות יתרון ביצועים משמעותי של שימוש ב-I/O של שקע חופף באמצעות Windows NT IOCPs.

חסימה ומצב שאינו חוסם

כאשר socket נוצר, כברירת מחדל הוא socket חוסם. תחת פעולות I/O של שקע במצב חסימה, התחבר וקבל את הפעולות של כל החסימות עד להשלמת הפעולה המדוברת. כדי לשנות את מצב הפעולה של socket ממצב חסימה למצב שאינו חוסם, באפשרותך להשתמש ב-Wsaאסינכרונית Cselect, ב-WSAEventSelect או בפקודה FIONBIO בקריאת ה-API של השקע המקומי. Wsa, מפות הודעות socket להודעות Windows והוא המודל הטוב ביותר עבור יישום GUI משורשר יחיד. WSAEventSelect משתמש ב-Wsaenumnetnet כדי לקבוע את טבעו של הודעת השקע באירוע האיתות ולמפות הודעות socket על-ידי איתות לאירוע. זהו מודל שימושי עבור יישומים שאינם מסוג GUI שאין בהם משאבת הודעה, כגון יישום שירות של Windows NT. הפקודה FIONBIO בקריאת ה-API הiocממקמת את השקע במצב שאינו חוסם. אך עליך לסקור את מצב השקע באמצעות ה-API הנבחר. עדכון: הגדרת SO_RCVBUF לאפס עם קבל חופף אינה נחוצה עבור Windows 2000, אשר יכול ישירות להעתיק את הנתונים למאגר קבל של היישום. הגדרת SO_SNDBUF לאפס עם שליחה חופפת ב-Windows 2000 עדיין יש את אותו יתרון של שמירת עותק זיכרון אחד כמו ב-Windows NT 4.0. חשוב גם כי היישום מנפיק מספר שליחה או recv מצטיינים של שלח אם היישום קובע את מאגר המחסנית המתאים ל -0.