كيفية قراءة واصفات الملفات المتعددة باستخدام EPOLL_SELECT مع Epollet؟
سؤال
رجل إيبول:
The suggested way to use epoll as an edge-triggered (EPOLLET) interface is as follows:
i with nonblocking file descriptors; and
ii by waiting for an event only after read(2) or write(2) return EAGAIN.
تخيل أن لدينا اثنين من FDS: الأول هو السلبي ، والبيانات المتاحة فقط في بعض الأحيان ، والثانية نشطة ، والبيانات فقط في بعض الأحيان غير متوفرة.
عاد epoll_wait بحيث يمكننا قراءة كليهما. لقد قرأنا {الأول ، من الثانية} في حلقة (بدون مكالمات إلى EPOLL_WAIT بسببها قد تمنع فجأة بينما لا تزال البيانات متوفرة).
الآن عاد واصف الملف الأول EAGAIN على القراءة.
ماذا أفعل؟
- إذا واصلنا قراءة FD الثانية في حلقة (بدون مكالمات إلى EPOLL_WAIT) ، فيمكننا تفويت أن البيانات قد أصبحت متاحة في FOR FD. سوف تقرأ وقراءة وقراءة بدون إياجين.
- إذا كنا "سنشاور" مع EPOLL_WAIT قبل كل قراءة من FD الثاني ، فقد تمنع EPOLL_WAIT فجأة بسبب عدم تغيير أي شيء من المكالمة السابقة (لا تزال البيانات غير متوفرة في FD الأولى ولا تزال متوفرة في FD الثانية).
كيف تستمر في معالجة FD الثانية ، ولكن دون أن تنسى FD FOR؟
تحديث: تم العثور على شيء آخر: رجل epoll_wait:
while specifying timeout equal to zero makes epoll_wait() to return immediately even if no events are available
مع هذا يمكنني تعداد الأحداث لـ FDS حتى لو لم تكن هناك أحداث.
المحلول
إذا كان FD2 قابلاً للقراءة باستمرار ، فقد تفكر في أن EPOLL غير مناسب لذلك. قد يكون الأمر يستحق الغزل من خيط فقط للجلوس وقراءته.
خلاف ذلك ، اقرأ FD2 في حلقة حتى يتم استنزافها ولكن في الحلقة ، تحاول قراءة FD1 بمجرد كل X مرات. إذا كان FD1 يحتوي على بيانات ، فاقرأها. إذا لم يكن الأمر كذلك ، فستحصل على EAGAIN ، أعد تعيين عداد X والعودة إلى قراءة FD2. عندما يتم استنزاف كلاهما ، تعود إلى Epoll_Wait.
شيء مثل:
count = 1;
while (true)
{
read fd2;
if (EAGAIN)
break;
else
process data;
count--;
if (! count)
{
while (true)
{
read fd1;
if (EAGAIN)
count = 10;
break;
else
process data;
}
}
}