0Pricing
C++ Academy · درس

الإدخال والإخراج غير المتزامنين باستخدام epoll وkqueue

وسّع نطاق البرنامج للتعامل مع اتصالات كثيرة باستخدام epoll في Linux وkqueue في BSD أو macOS.

الإدخال والإخراج غير المتزامنين باستخدام epoll وkqueue درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

لماذا الإدخال والإخراج غير المتزامن؟

لا يتوسع نموذج خيط تنفيذ لكل اتصال ليخدم آلاف العملاء أو ملايينهم. يتيح الإدخال والإخراج غير المتزامن لخيط تنفيذ واحد معالجة مقابس عديدة، من خلال الانتظار حتى يصبح أيٌّ منها قابلًا للقراءة أو الكتابة.

Linux: epoll

يوفر Linux واجهة أحداث قابلة للتوسع. أضف واصفات الملفات إلى مثيل epoll، ثم انتظر الأحداث على أيٍّ منها.

#include <sys/epoll.h>
int epfd = epoll_create1(0);
epoll_event ev{};
ev.events = EPOLLIN;
ev.data.fd = sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev);

انتظار الأحداث

تحجب epoll_wait التنفيذ حتى تتوفر أحداث، ثم تعيد الواصفات الجاهزة.

epoll_event events[64];
int n = epoll_wait(epfd, events, 64, -1);
for (int i = 0; i < n; ++i) {
    int fd = events[i].data.fd;
    handle_io(fd);
}

التفعيل بالحافة مقابل التفعيل بالمستوى

يوجد وضعان:

  • التفعيل بالمستوى (الافتراضي) — يواصل epoll الإبلاغ ما دام الشرط قائمًا
  • التفعيل بالحافة (EPOLLET) — يُبلغ عن تغيّر الحالة فقط؛ ويجب تفريغ المقبس بالكامل في كل مرة

macOS وBSD: kqueue

يمثل kqueue النظير الخاص بـ BSD لـ epoll، وهو متاح أيضًا على macOS. المفهوم متشابه، لكن واجهة برمجة التطبيقات مختلفة.

#include <sys/event.h>
int kq = kqueue();
struct kevent ev;
EV_SET(&ev, sock, EVFILT_READ, EV_ADD, 0, 0, nullptr);
kevent(kq, &ev, 1, nullptr, 0, nullptr);

Windows: IOCP

يستخدم Windows منافذ إكمال الإدخال والإخراج (IOCP)، وهو نموذج قائم على الإكمال (الإشعار عند الانتهاء) بدلًا من نموذج الجاهزية الذي يستخدمه epoll وkqueue.

المقابس غير الحاجبة

اضبط المقابس على الوضع غير الحاجب باستخدام fcntl(fd, F_SETFL, O_NONBLOCK). وإلا فقد تحجب عمليات القراءة والكتابة حلقة الأحداث بأكملها.

نمط حلقة الأحداث

حلقة تعمل إلى ما لا نهاية:

  1. انتظر الأحداث الجاهزة
  2. لكل حدث، نفّذ عمليات الإدخال والإخراج حتى تصبح العملية حاجبة
  3. كرر

معالجة عدد كبير من العملاء

يمكن لخيط تنفيذ واحد خاص بـ epoll معالجة عشرات الآلاف من الاتصالات المتزامنة، وهي مشكلة C10K. وتدفع الأنظمة الحديثة هذا العدد إلى الملايين.

الأخطاء الشائعة

انتبه إلى ما يلي:

  • نسيان ضبط الوضع غير الحاجب
  • استخدام التفعيل بالحافة دون تفريغ المقبس
  • عدم إزالة واصفات الملفات المغلقة من مجموعة epoll
  • تسرّب مخازن مؤقتة لكل اتصال

التغليفات ذات المستوى الأعلى

تُعد كتابة حلقة epoll يدويًا عرضة للأخطاء. استخدم libuv أو libevent أو Boost.Asio في الشيفرة الإنتاجية؛ فهي تخفي اختلافات المنصات وتوفر حلقات إدخال وإخراج مختبرة.

الإدخال والإخراج غير المتزامن مقابل خيوط التنفيذ

يتميز الإدخال والإخراج غير المتزامن بقابلية توسع أكبر، لكنه أصعب في الكتابة. بالنسبة إلى خوادم تضم بضعة آلاف من الاتصالات، يكون نموذج خيط تنفيذ لكل اتصال أبسط. اختر بناءً على الحمل المتوقع.

تحقق سريع

ما الفرق بين وضعي التفعيل بالحافة والتفعيل بالمستوى في epoll؟

مراجعة

يتوسع الإدخال والإخراج غير المتزامن ليخدم تزامنًا هائلًا من خلال معالجة مقابس عديدة في خيط تنفيذ واحد. يستخدم Linux epoll، وتستخدم BSD وmacOS ‏kqueue، بينما يستخدم Windows ‏IOCP. اضبط المقابس على الوضع غير الحاجب. وفي الإنتاج، استخدم مكتبة مثل Asio أو libuv أو libevent بدلًا من كتابة حلقة الأحداث يدويًا.

الأسئلة الشائعة

هل درس «الإدخال والإخراج غير المتزامنين باستخدام epoll وkqueue» مجاني؟

نعم — نص درس «الإدخال والإخراج غير المتزامنين باستخدام epoll وkqueue» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «الإدخال والإخراج غير المتزامنين باستخدام epoll وkqueue»؟

وسّع نطاق البرنامج للتعامل مع اتصالات كثيرة باستخدام epoll في Linux وkqueue في BSD أو macOS. تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «الإدخال والإخراج غير المتزامنين باستخدام epoll وkqueue»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. واجهة BSD Sockets API في C++
  2. بناء خادم صدى TCP
  3. الإدخال والإخراج غير المتزامنين باستخدام epoll وkqueue
  4. استخدام Boost Asio للإدخال والإخراج غير المتزامنين الحديثين
← العودة إلى C++ Academy