سؤال

while (xxx) {
    timeout.tv_sec=TIMEOUT;
    timeout.tv_usec=0;
    FD_ZERO(&set); 
    FD_SET(sd,&set);

    switch (select(FD_SETSIZE,&set,NULL,NULL,&timeout))
    xxxxx
}

يعمل بشكل جيد، ولكن

FD_ZERO(&set); 
FD_SET(sd,&set);

while (xxx) {
    timeout.tv_sec=TIMEOUT;
    timeout.tv_usec=0;

    switch (select(FD_SETSIZE,&set,NULL,NULL,&timeout))
    xxxxx
}

لا.إنه يعمل في المرة الأولى، ولكن في المرة التالية التي يتم فيها تشغيله خلال الحلقة، فإنه يحصل على مهلة حتى لو استقبل مقبس sd البيانات.يبدو لي أنه من إهدار الموارد أن تضطر إلى إفراغ وتعبئة المجموعة في كل مرة.

هل لدى أي شخص تفسير جيد لسبب ذلك، وربما أفضل من ذلك، اقتراح حول كيفية تجنبه؟

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

المحلول

حدد يعدل الوسائط الخاصة به.يجب عليك حقًا إعادة تهيئته في كل مرة.

إذا كنت قلقًا بشأن النفقات العامة، فإن تكلفة معالجة FD_SET الكاملة في النواة تكون أكثر أهمية إلى حد ما من تكلفة FD_ZERO.قد ترغب في تمرير الحد الأقصى من fd فقط، وليس FD_SETSZIZE، لتقليل معالجة kernel.في المثال الخاص بك:

switch (select((sd + 1),&set,NULL,NULL,&timeout))

بالنسبة للحالة الأكثر تعقيدًا التي تحتوي على عدة fds، عادةً ما ينتهي بك الأمر إلى الحفاظ على متغير max:

FD_SET(sd,&set);
if (sd > max) max = sd;
... repeat many times...

switch (select((max + 1),&set,NULL,NULL,&timeout))


إذا كان لديك عدد كبير من واصفات الملفات وتشعر بالقلق بشأن العبء الزائد عن برمجتها، فيجب عليك إلقاء نظرة على بعض البدائل لتحديد ().لم تذكر نظام التشغيل الذي تستخدمه، ولكن بالنسبة لأنظمة التشغيل المشابهة لـ Unix، هناك عدد قليل منها:

  • لنظام التشغيل Linux، epoll()
  • لـ FreeBSD/NetBSD/OpenBSD/MacOS X، kqueue()
  • لسولاريس، /dev/poll

تختلف واجهات برمجة التطبيقات (APIs)، ولكنها جميعها في الأساس واجهة kernel ذات حالة للحفاظ على مجموعة من أوصاف الملفات النشطة.بمجرد إضافة fd إلى المجموعة، سيتم إعلامك بالأحداث الموجودة على هذا fd دون الحاجة إلى تمريره باستمرار مرة أخرى.

نصائح أخرى

وقراءة الصفحة رجل مختارة. مجموعة عاد ليست سوى واصفات الملف الذي هم على استعداد لاستخدامها. من المفترض أن استخدام FD_ISSET للتحقق كل واحد إذا تم تعيين ذلك أم لا.

وتهيئة دائما الحق fd_set قبل استخدامه.

وهذه هي الطريقة المختارة الأعمال. أنه يعمل بشكل أفضل، وأكثر منطقية، إذا كان لديك مقبس أكثر من واحد. هذا النوع من هذه النقطة: كنت اختيار عبر العديد من مآخذ. إذا كنت ترغب في قراءة من مأخذ واحد، وقراءة فقط أو ريكف ذلك.

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