.\" -*- coding: UTF-8 -*- .\" Copyright 2003, Davide Libenzi .\" Copyright, the authors of the Linux man-pages project .\" .\" SPDX-License-Identifier: GPL-2.0-or-later .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH epoll 7 "8 فبراير 2026" "صفحات دليل لينكس 6.18" .SH الاسم epoll \- مرفق إعلام أحداث الإدخال/الإخراج .SH موجز .nf \fB#include \fP .fi .SH الوصف تقوم واجهة برمجة التطبيقات \fBepoll\fP بمهمة مشابهة لـ \fBpoll\fP(2): مراقبة واصفات ملفات متعددة لمعرفة ما إذا كان الإدخال/الإخراج ممكنًا على أي منها. يمكن استخدام واجهة برمجة التطبيقات \fBepoll\fP إما كواجهة محفزة بالحافة أو محفزة بالمستوى وتتوسع جيدًا لأعداد كبيرة من واصفات الملفات المراقبة. .P المفهوم المركزي لواجهة برمجة التطبيقات \fBepoll\fP هو \fIمثيل\fP \fBepoll\fP، وهو بنية بيانات داخل النواة يمكن، من منظور مساحة المستخدم، اعتبارها حاوية لقائمتين: .IP \[bu] 3 قائمة \fIالاهتمام\fP (تسمى أحيانًا مجموعة \fBepoll\fP): مجموعة واصفات الملفات التي سجلت العملية اهتمامًا بمراقبتها. .IP \[bu] قائمة \fIالجاهزية\fP: مجموعة واصفات الملفات "الجاهزة" للإدخال/الإخراج. قائمة الجاهزية هي مجموعة فرعية من (أو، بشكل أكثر دقة، مجموعة مراجع لـ) واصفات الملفات في قائمة الاهتمام. تُملئ قائمة الجاهزية ديناميكيًا بواسطة النواة نتيجة لنشاط الإدخال/الإخراج على واصفات الملفات تلك. .P تُوفر استدعاءات النظام التالية لإنشاء وإدارة مثيل \fBepoll\fP: .IP \[bu] 3 يقوم \fBepoll_create\fP(2) بإنشاء مثيل \fBepoll\fP جديد ويعيد واصف ملف يشير إلى ذلك المثيل. (يقوم \fBepoll_create1\fP(2) الأحدث بتوسيع وظائف \fBepoll_create\fP(2).) .IP \[bu] ثم يُسجل الاهتمام بواصفات ملفات معينة عبر \fBepoll_ctl\fP(2)، الذي يضيف عناصر إلى قائمة الاهتمام لمثيل \fBepoll\fP. .IP \[bu] .\" ينتظر \fBepoll_wait\fP(2) أحداث الإدخال/الإخراج، مما يحجب الخيط المستدعي إذا لم تكن أي أحداث متاحة حاليًا. (يمكن اعتبار استدعاء النظام هذا كجلب عناصر من قائمة الجاهزية لمثيل \fBepoll\fP.) .SS "محفز بالمستوى ومحفز بالحافة" واجهة توزيع الأحداث \fBepoll\fP قادرة على التصرف كمحفز بالحافة (ET) ومحفز بالمستوى (LT). يمكن وصف الفرق بين الآليتين على النحو التالي. افترض أن هذا السيناريو يحدث: .IP (1) 5 يُسجل واصف الملف الذي يمثل جانب القراءة من أنبوب (\fIrfd\fP) على مثيل \fBepoll\fP. .IP (2) يكتب كاتب الأنبوب 2\ كيلوبايت من البيانات على جانب الكتابة من الأنبوب. .IP (3) يُستدعى \fBepoll_wait\fP(2) الذي سيعيد \fIrfd\fP كواصف ملف جاهز. .IP (4) يقرأ قارئ الأنبوب 1\ كيلوبايت من البيانات من \fIrfd\fP. .IP (5) يُستدعى \fBepoll_wait\fP(2). .P إذا أُضيف واصف الملف \fIrfd\fP إلى واجهة \fBepoll\fP باستخدام العلم \fBEPOLLET\fP (محفز بالحافة)، فإن استدعاء \fBepoll_wait\fP(2) الذي تم في الخطوة \fB5\fP سيعلق على الأرجح على الرغم من البيانات المتاحة الموجودة في مخزن الإدخال المؤقت للملف؛ وفي الوقت نفسه، قد يتوقع النظير البعيد استجابة بناءً على البيانات التي أرسلها بالفعل. السبب في ذلك هو أن الوضع المحفز بالحافة يسلم الأحداث فقط عند حدوث تغييرات على واصف الملف المراقب، أي أنه يُولّد حدث عند كل استلام لكتلة من البيانات. لذا، في الخطوة \fB5\fP قد ينتهي الأمر بالمستدعي بانتظار بعض البيانات الموجودة بالفعل داخل مخزن الإدخال المؤقت. في المثال أعلاه، سيُولّد حدث على \fIrfd\fP بسبب الكتابة التي تمت في \fB2\fP ويُستهلك الحدث في \fB3\fP. نظرًا لأن عملية القراءة التي تمت في \fB4\fP لا تستهلك بيانات المخزن المؤقت بالكامل، فإن استدعاء \fBepoll_wait\fP(2) الذي تم في الخطوة \fB5\fP قد يحظر إلى أجل غير مسمى. .P يجب على تطبيق يستخدم العلم \fBEPOLLET\fP استخدام واصفات ملفات غير محظورة لتجنب تجويع مهمة تتعامل مع واصفات ملفات متعددة بسبب قراءة أو كتابة محظورة. الطريقة المقترحة لاستخدام \fBepoll\fP كواجهة محفزة بالحافة (\fBEPOLLET\fP) هي كما يلي: .IP (1) 5 مع واصفات ملفات غير محظورة؛ و .IP (2) بانتظار حدث فقط بعد أن يعيد \fBread\fP(2) أو \fBwrite\fP(2) \fBEAGAIN\fP. .P على النقيض، عند استخدامه كواجهة محفزة بالمستوى (المبدئي، عندما لا يُحدد \fBEPOLLET\fP)، فإن \fBepoll\fP هو ببساطة \fBpoll\fP(2) أسرع، ويمكن استخدامه أينما اُستخدم الأخير لأنه يشارك نفس الدلالات. .P نظرًا لأنه حتى مع \fBepoll\fP المحفز بالحافة، يمكن توليد أحداث متعددة عند استلام كتل متعددة من البيانات، فإن لدى المستدعي خيار تحديد العلم \fBEPOLLONESHOT\fP، لإخبار \fBepoll\fP بتعطيل واصف الملف المرتبط بعد استلام حدث مع \fBepoll_wait\fP(2). عند تحديد العلم \fBEPOLLONESHOT\fP، تقع على عاتق المستدعي مسؤولية إعادة تسليح واصف الملف باستخدام \fBepoll_ctl\fP(2) مع \fBEPOLL_CTL_MOD\fP. .P .\" إذا حُظر تعدد الخيوط (أو عمليات، إذا ورثت العمليات الفرعية واصف ملف \fBepoll\fP عبر \fBfork\fP(2)) في \fBepoll_wait\fP(2) منتظرة نفس واصف ملف epoll وأصبح واصف ملف في قائمة الاهتمام محدد للإعلام المحفز بالحافة (\fBEPOLLET\fP) جاهزًا، يُوقظ خيط واحد فقط (أو عملية) من \fBepoll_wait\fP(2). يوفر هذا تحسينًا مفيدًا لتجنب إيقاظ "القطيع المتدافع" في بعض السيناريوهات. .SS "التفاعل مع التعليق الآلي" إذا كان النظام في وضع \fBautosleep\fP عبر \fI/sys/power/autosleep\fP وحدث حدث يوقظ الجهاز من التعليق؛ فسيُبقي برنامج تشغيل الجهاز الجهاز مستيقظًا فقط حتى يُوضع ذلك الحدث في قائمة الانتظار. لإبقاء الجهاز مستيقظًا حتى يُعالج الحدث، من الضروري استخدام علامة \fBepoll_ctl\fP(2) \fBEPOLLWAKEUP\fP. .P عند تعيين علامة \fBEPOLLWAKEUP\fP في حقل \fBevents\fP لـ \fIstruct epoll_event\fP، سيُبقي النظام مستيقظًا من لحظة وضع الحدث في قائمة الانتظار، عبر استدعاء \fBepoll_wait\fP(2) الذي يُرجع الحدث حتى استدعاء \fBepoll_wait\fP(2) التالي. إذا كان يجب أن يُبقي الحدث النظام مستيقظًا بعد ذلك الوقت، فيجب أخذ \fIwake_lock\fP منفصل قبل استدعاء \fBepoll_wait\fP(2) الثاني. .SS "واجهات /proc" .\" Following was added in Linux 2.6.28, but them removed in Linux 2.6.29 .\" .TP .\" .IR /proc/sys/fs/epoll/max_user_instances " (since Linux 2.6.28)" .\" This specifies an upper limit on the number of epoll instances .\" that can be created per real user ID. يمكن استخدام الواجهات التالية للحد من مقدار ذاكرة النواة التي يستهلكها epoll: .TP \fI/proc/sys/fs/epoll/max_user_watches\fP (منذ Linux 2.6.28) .\" Linux 2.6.29 (in Linux 2.6.28, the default was 1/32 of lowmem) يحدد هذا حدًا للعدد الإجمالي لوصفات الملفات التي يمكن لمستخدم تسجيلها عبر جميع مثيلات epoll على النظام. الحد هو لكل معرف مستخدم حقيقي. تكلف كل واصف ملف مسجل حوالي 90 بايت على نواة 32 بت، وحوالي 160 بايت على نواة 64 بت. حاليًا، القيمة المبدئية لـ \fImax_user_watches\fP هي 1/25 (4%) من الذاكرة المنخفضة المتاحة، مقسومة على تكلفة التسجيل بالبايت. .SS "مثال للاستخدام المقترح" بينما استخدام \fBepoll\fP عند توظيفه كواجهة محفزة بالمستوى له نفس دلالات \fBpoll\fP(2)، فإن الاستخدام المحفز بالحافة يتطلب مزيدًا من التوضيح لتجنب التوقف في حلقة أحداث التطبيق. في هذا المثال، المستمع هو مقبس غير محظور اُستدعيت \fBlisten\fP(2) عليه. تستخدم الدالة \fIdo_use_fd()\fP واصف الملف الجديد الجاهز حتى يُرجع \fBEAGAIN\fP بواسطة إما \fBread\fP(2) أو \fBwrite\fP(2). يجب على تطبيق آلة الحالة الموجه بالأحداث، بعد استلام \fBEAGAIN\fP، تسجيل حالته الحالية بحيث في الاستدعاء التالي لـ \fIdo_use_fd()\fP سيستمر في \fBread\fP(2) أو \fBwrite\fP(2) من حيث توقف سابقًا. .P .in +4n .EX #define MAX_EVENTS 10 struct epoll_event ev, events[MAX_EVENTS]; int listen_sock, conn_sock, nfds, epollfd; \& /* Code to set up listening socket, \[aq]listen_sock\[aq], (socket(), bind(), listen()) omitted. */ \& epollfd = epoll_create1(0); if (epollfd == \-1) { perror("epoll_create1"); exit(EXIT_FAILURE); } \& ev.events = EPOLLIN; ev.data.fd = listen_sock; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == \-1) { perror("epoll_ctl: listen_sock"); exit(EXIT_FAILURE); } \& for (;;) { nfds = epoll_wait(epollfd, events, MAX_EVENTS, \-1); if (nfds == \-1) { perror("epoll_wait"); exit(EXIT_FAILURE); } \& for (n = 0; n < nfds; ++n) { if (events[n].data.fd == listen_sock) { conn_sock = accept(listen_sock, (struct sockaddr *) &addr, &addrlen); if (conn_sock == \-1) { perror("accept"); exit(EXIT_FAILURE); } setnonblocking(conn_sock); ev.events = EPOLLIN | EPOLLET; ev.data.fd = conn_sock; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &ev) == \-1) { perror("epoll_ctl: conn_sock"); exit(EXIT_FAILURE); } } else { do_use_fd(events[n].data.fd); } } } .EE .in .P عند استخدامه كواجهة محفزة بالحافة، لأسباب تتعلق بالأداء، من الممكن إضافة واصف الملف داخل واجهة \fBepoll\fP (\fBEPOLL_CTL_ADD\fP) مرة واحدة عن طريق تحديد (\fBEPOLLIN\fP|\fBEPOLLOUT\fP). يتيح لك هذا تجنب التبديل المستمر بين \fBEPOLLIN\fP و \fBEPOLLOUT\fP باستدعاء \fBepoll_ctl\fP(2) مع \fBEPOLL_CTL_MOD\fP. .SS "أسئلة وأجوبة" .IP \[bu] 3 ما هو المفتاح المستخدم للتمييز بين واصفات الملفات المسجلة في قائمة الاهتمام؟ .IP المفتاح هو مزيج من رقم واصف الملف ووصف الملف المفتوح (المعروف أيضًا باسم "مقبض الملف المفتوح"، التمثيل الداخلي للنواة لملف مفتوح). .IP \[bu] ماذا يحدث إذا سجلت نفس واصف الملف على مثيل \fBepoll\fP مرتين؟ .IP .\" But a file descriptor duplicated by fork(2) can't be added to the .\" set, because the [file *, fd] pair is already in the epoll set. .\" That is a somewhat ugly inconsistency. On the one hand, a child process .\" cannot add the duplicate file descriptor to the epoll set. (In every .\" other case that I can think of, file descriptors duplicated by fork have .\" similar semantics to file descriptors duplicated by dup() and friends.) On .\" the other hand, the very fact that the child has a duplicate of the .\" file descriptor means that even if the parent closes its file descriptor, .\" then epoll_wait() in the parent will continue to receive notifications for .\" that file descriptor because of the duplicated file descriptor in the child. .\" .\" See http://thread.gmane.org/gmane.linux.kernel/596462/ .\" "epoll design problems with common fork/exec patterns" .\" .\" mtk, Feb 2008 ستحصل على الأرجح على \fBEEXIST\fP. ومع ذلك، من الممكن إضافة واصف ملف مكرر (\fBdup\fP(2), \fBdup2\fP(2), \fBfcntl\fP(2) \fBF_DUPFD\fP) إلى نفس مثيل \fBepoll\fP. يمكن أن تكون هذه تقنية مفيدة لتصفية الأحداث، إذا سُجلت واصفات الملفات المكررة بأقنعة \fIevents\fP مختلفة. .IP \[bu] هل يمكن لمثيلين من \fBepoll\fP الانتظار لنفس واصف الملف؟ إذا كان الأمر كذلك، هل يُبلغ عن الأحداث لكلا واصفي ملف \fBepoll\fP؟ .IP نعم، وسيُبلغ عن الأحداث لكليهما. ومع ذلك، قد تكون هناك حاجة إلى برمجة دقيقة للقيام بذلك بشكل صحيح. .IP \[bu] هل واصف ملف \fBepoll\fP نفسه قابل للاستقصاء/epoll/الاختيار؟ .IP نعم. إذا كان واصف ملف \fBepoll\fP يحتوي على أحداث في انتظار، فسيشير إلى أنه قابل للقراءة. .IP \[bu] ماذا يحدث إذا حاول المرء وضع واصف ملف \fBepoll\fP في مجموعة واصفات الملفات الخاصة به؟ .IP يفشل استدعاء \fBepoll_ctl\fP(2) (\fBEINVAL\fP). ومع ذلك، يمكنك إضافة واصف ملف \fBepoll\fP داخل مجموعة واصفات ملف \fBepoll\fP أخرى. .IP \[bu] هل يمكنني إرسال واصف ملف \fBepoll\fP عبر مقبس نطاق UNIX إلى عملية أخرى؟ .IP نعم، ولكن ليس من المنطقي القيام بذلك، لأن العملية المستقبلة لن يكون لديها نسخ من واصفات الملفات في قائمة الاهتمام. .IP \[bu] هل سيؤدي إغلاق واصف ملف إلى إزالته من جميع قوائم اهتمام \fBepoll\fP؟ .IP نعم، ولكن كن على دراية بالنقطة التالية. واصف الملف هو مرجع لوصف ملف مفتوح (انظر \fBopen\fP(2)). كلما كُرر واصف ملف عبر \fBdup\fP(2), \fBdup2\fP(2), \fBfcntl\fP(2) \fBF_DUPFD\fP, أو \fBfork\fP(2)، يُنشئ واصف ملف جديد يشير إلى نفس وصف الملف المفتوح. يستمر وصف الملف المفتوح في الوجود حتى تُغلق جميع واصفات الملفات التي تشير إليه. .IP يُزال واصف الملف من قائمة الاهتمام فقط بعد إغلاق جميع واصفات الملفات التي تشير إلى وصف الملف المفتوح الأساسي. هذا يعني أنه حتى بعد إغلاق واصف ملف يمثل جزءًا من قائمة الاهتمام، قد يُبلغ عن أحداث لذلك واصف الملف إذا بقيت واصفات ملفات أخرى تشير إلى نفس وصف الملف الأساسي مفتوحة. لمنع حدوث ذلك، يجب إزالة واصف الملف صراحةً من قائمة الاهتمام (باستخدام \fBepoll_ctl\fP(2) \fBEPOLL_CTL_DEL\fP) قبل تكراره. بدلاً من ذلك، يجب على التطبيق التأكد من إغلاق جميع واصفات الملفات (والذي قد يكون صعبًا إذا كُررت واصفات الملفات خلف الكواليس بواسطة دوال مكتبة استخدمت \fBdup\fP(2) أو \fBfork\fP(2)). .IP \[bu] إذا حدث أكثر من حدث واحد بين استدعاءات \fBepoll_wait\fP(2)، هل تُجمع أم يُبلغ عنها بشكل منفصل؟ .IP ستُجمع. .IP \[bu] هل تؤثر عملية على واصف ملف على الأحداث المجموعة فعلًا ولكن لم يُبلغ عنها بعد؟ .IP يمكنك إجراء عمليتين على واصف ملف موجود. الإزالة ستكون غير ذات معنى لهذه الحالة. التعديل سيعيد قراءة الإدخال/الإخراج المتاح. .IP \[bu] هل أحتاج إلى القراءة/الكتابة باستمرار من واصف ملف حتى \fBEAGAIN\fP عند استخدام علامة \fBEPOLLET\fP (السلوك المحفز بالحافة)؟ .IP استلام حدث من \fBepoll_wait\fP(2) يجب أن يشير لك أن واصف الملف هذا جاهز لعملية الإدخال/الإخراج المطلوبة. يجب أن تعتبره جاهزًا حتى تؤدي القراءة/الكتابة التالية (غير المحظورة) إلى \fBEAGAIN\fP. متى وكيف ستستخدم واصف الملف يعود إليك بالكامل. .IP بالنسبة للملفات الموجهة للحزم/الرموز (مثل مقبس البيانات، الطرفية في الوضع القانوني)، الطريقة الوحيدة لاكتشاف نهاية مساحة الإدخال/الإخراج للقراءة/الكتابة هي الاستمرار في القراءة/الكتابة حتى \fBEAGAIN\fP. .IP بالنسبة للملفات الموجهة للتيار (مثل الأنبوب، FIFO، مقبس التيار)، يمكن أيضًا اكتشاف حالة استنفاد مساحة الإدخال/الإخراج للقراءة/الكتابة عن طريق التحقق من كمية البيانات المقروءة من / المكتوبة إلى واصف الملف الهدف. على سبيل المثال، إذا استدعيت \fBread\fP(2) لطلب قراءة كمية معينة من البيانات وأرجعت \fBread\fP(2) عددًا أقل من البايتات، يمكنك التأكد من استنفاد مساحة الإدخال/الإخراج للقراءة لواصف الملف. نفس الشيء صحيح عند الكتابة باستخدام \fBwrite\fP(2). (تجنب هذه التقنية الأخيرة إذا لم تستطع ضمان أن واصف الملف المراقب يشير دائمًا إلى ملف موجه للتيار.) .SS "المزالق المحتملة وطرق تجنبها" .IP \[bu] 3 \fBالتجويع (محفز بالحافة)\fP .IP إذا كانت هناك كمية كبيرة من مساحة الإدخال/الإخراج، فمن الممكن أن يؤدي محاولة تفريغها إلى عدم معالجة الملفات الأخرى مما يسبب التجويع. (هذه المشكلة ليست خاصة بـ \fBepoll\fP.) .IP الحل هو الاحتفاظ بقائمة جاهزة ووضع علامة على واصف الملف كجاهز في بنية البيانات المرتبطة به، مما يسمح للتطبيق بتذكر الملفات التي تحتاج إلى معالجة ولكن مع الاستمرار في التناوب الدائري بين جميع الملفات الجاهزة. هذا يدعم أيضًا تجاهل الأحداث اللاحقة التي تستلمها لواصفات الملفات الجاهزة بالفعل. .IP \[bu] \fBإذا كنت تستخدم خبيئة أحداث...\fP .IP إذا كنت تستخدم خبيئة أحداث أو تخزن جميع واصفات الملفات المعادة من \fBepoll_wait\fP(2)، فتأكد من توفير طريقة لوضع علامة على إغلاقها ديناميكيًا (أي ناتج عن معالجة حدث سابق). افترض أنك تستلم 100 حدث من \fBepoll_wait\fP(2)، وفي الحدث #47 تسبب حالة في إغلاق الحدث #13. إذا أزلت البنية واستدعيت \fBclose\fP(2) لواصف الملف للحدث #13، فقد تظل خبيئة الأحداث تقول أن هناك أحداثًا تنتظر واصف الملف هذا مما يسبب ارتباكًا. .IP أحد الحلول لذلك هو استدعاء، أثناء معالجة الحدث 47، \fBepoll_ctl\fP(\fBEPOLL_CTL_DEL\fP) لحذف واصف الملف 13 و \fBclose\fP(2)، ثم وضع علامة على بنية البيانات المرتبطة به كمزالة وربطها بقائمة تنظيف. إذا وجدت حدثًا آخر لواصف الملف 13 في معالجتك الدفعية، ستكتشف أن واصف الملف قد أزيل سابقًا ولن يكون هناك ارتباك. .SH الإصدارات بعض الأنظمة الأخرى توفر آليات مماثلة؛ على سبيل المثال، FreeBSD لديها \fIkqueue\fP، وSolaris لديها \fI/dev/poll\fP. .SH المعايير لينكس. .SH التاريخ .\" Its interface should be finalized in Linux 2.5.66. لينكس 2.5.44. glibc 2.3.2. .SH ملاحظات يمكن عرض مجموعة واصفات الملفات المُراقبة عبر واصف ملف epoll من خلال الإدخال الخاص بواصف ملف epoll في دليل \fI/proc/\fPpid\fI/fdinfo\fP للعملية. انظر \fBproc\fP(5) لمزيد من التفاصيل. .P يمكن استخدام عملية \fBkcmp\fP(2) \fBKCMP_EPOLL_TFD\fP لاختبار ما إذا كان واصف ملف موجودًا في مثيل epoll. .SH "انظر أيضًا" \fBepoll_create\fP(2)، \fBepoll_create1\fP(2)، \fBepoll_ctl\fP(2)، \fBepoll_wait\fP(2)، \fBioctl_eventpoll\fP(2)، \fBpoll\fP(2)، \fBselect\fP(2) .PP .SH ترجمة تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي و # . .PP هذه الترجمة هي وثيقة مجانية؛ راجع .UR https://www.gnu.org/licenses/gpl-3.0.html رخصة جنو العامة الإصدار 3 .UE أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات. .PP إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: .MT kde-l10n-ar@kde.org .ME .