سؤال

يقول ManPage EPOLL أن FD المسجل لدى Epollet (Edge الذي تم تشغيله) لا ينبغي أن يخطر مرتين Epollin إذا لم يتم قراءة أي قراءة.
لذلك بعد Epollin ، تحتاج إلى تفريغ المخزن المؤقت قبل أن تتمكن Epoll_Wait من إعادة Epollin جديدة على بيانات جديدة.

ومع ذلك ، أواجه مشاكل في هذا النهج لأنني أرى أحداث Epollin المكررة ل FDS لم تمسها.
هذا هو إخراج Strace ، 0x200 هو epollrdhup لم يتم تعريفه بعد في رؤوس glibc الخاصة بي ولكن محددة في kernel.

30285 epoll_ctl(3, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET|0x2000, {u32=9, u64=9}}) = 0
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3,  <unfinished ...>
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = 0
30306 recv(9, "7u\0\0\10\345\241\312\t\20\f\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30"..., 20000, 0) = 20000
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = -1 ENOENT (No such file or directory)
30305 recv(9, " \31(C0\17\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30\200\10 \31("..., 20000, 0) = 10011

لذلك ، بعد إضافة رقم FD رقم 9 ، أتلقى أحداث Epollin متتالية قبل أن أتخلى عن واصف الملف ، يوضح Trace Syscall كيف أقوم بحذف FD قبل القراءة ولكن يجب أن يحدث مرة واحدة فقط ، واحد لكل حدث.
لذا ، فأنا لا أقرأ Manpage بشكل صحيح أو شيء يعمل الآن هنا.

هل كانت مفيدة؟

المحلول

أعتقد أنك فاتتك هذا الجزء من epoll صفحة الرجل:

نظرًا لأنه حتى مع وجود أحداث متعددة من الأحداث التي يتم تشغيلها على الحافة ، يمكن إنشاء أحداث متعددة عند استلام أجزاء متعددة من البيانات ، فإن المتصل لديه خيار لتحديد EPOLLONESHOT العلم ، لإخبار Epoll لتعطيل واصف الملف المرتبط بعد استلام حدث مع epoll_wait(2). عندما EPOLLONESHOT تم تحديد العلم ، إنها مسؤولية المتصل بتعديل واصف الملف باستخدام epoll_ctl(2) مع EPOLL_CTL_MOD.

هذا هو: لقد حصلت على قطعتين من البيانات التي تصل في قائمة انتظار تلقيك قبل الأول read() حدث ، مما يعني أنك حصلت على حدثين EPOLL. انها تبدو مثل EPOLLONESHOT هو ما تتبعه ، والذي سيقوم بإزالة واصف الملف من مجموعة الاستطلاع عندما يحدث حدث على ذلك (لذلك لن تحتاج إلى القيام EPOLL_CTL_DEL).

نصائح أخرى

يعني TEDER TRIGGER (ما لم تكن قد استخدمت Epolloneshot) أنك ستحصل على حدث واحد عندما يدخل شيء ما في المخزن المؤقت (kernel).

وبالتالي ، إذا حصلت على حدث واحد من Epollin ولم تفعل شيئًا حيال ذلك ، فستحصل على Epollin آخر في المرة القادمة التي تصل فيها بعض البيانات إلى هذا الواصف - إذا لم تصل بيانات جديدة ، فلن تحصل على حدث رغم ذلك ، حتى لو لم تقم بذلك اقرأ أي بيانات كما هو موضح في الحدث الأول.

حسنًا ، بعبارة إيجاز ، يعني Epolloneshot أنه إذا لم تقرأ البيانات التي من المفترض أن تقرأها ، فسيتم تجاهلها.

عادة ، سيتم إخطارك بحدث لنفس البيانات إذا لم تقرأها. مع Epolloneshot ، ومع ذلك ، فإن عدم قراءة البيانات قانونية تمامًا وسيتم تجاهلها للتو. وبالتالي ، لن يتم إنشاء أي أحداث أخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top