Libxev هي حلقة حدث عبر منصة. يوفر Libxev تجريدًا موحدًا لحلقة الأحداث ل IO غير المحظور ، والمؤخيرات ، والإشارات ، والأحداث ، والمزيد التي تعمل على MacOS و Windows و Linux و Webassembly (المتصفح و WASI). إنه مكتوب بلطف ولكن يصدر واجهة برمجة تطبيقات متوافقة مع C (مما يجعله متوافقًا مع أي لغة يمكن أن تتواصل مع واجهات برمجة تطبيقات C).
حالة المشروع :؟ غير مستقرة ، جودة ألفا. قائمة الميزات جيدة جدًا عبر منصات متعددة ، ولكن هناك الكثير من الميزات المفقودة. لم يتم اختبار المشروع جيدًا في بيئات العالم الحقيقي ، وهناك الكثير من الفاكهة المنخفضة لتحسين الأداء. أنا لا أعدك بأي توافق في API في هذه المرحلة ، أيضًا. إذا كنت ترغب في الحصول على تطبيق حلقة أحداث جاهزة وعالية الجودة ، تحقق من Libuv ، Libev ، إلخ.
لماذا مكتبة حلقة حدث جديدة؟ بعض الأسباب. أولاً ، أعتقد أن Zig تفتقر إلى حلقة حدث معممة مماثلة لـ Libuv في الميزات ("المعمم" كونها كلمة أساسية هنا). ثانياً ، أردت إنشاء مكتبة كهذه حول أنماط تصميم IO_URING ، حتى تحاكي أسلوبها على رأس أولية OS الأخرى (الائتمان لهذا المنشور المدونة الرائع). ثلاثة ، أردت مكتبة حلقة حدث يمكن أن تبني إلى webassembly (كلاهما WASI و ALESTANDAND) والتي لم تتوافق بشكل جيد مع أهداف API للمكتبات الحالية دون إحضار شيء ثقيل للغاية مثل emscripten. الدافع لهذه المكتبة في المقام الأول هو خدش الحكة الخاصة بي!
منصة العرض. Linux ( io_uring و epoll ) ، MACOS ( kqueue ) ، Webassembly + WASI ( poll_oneoff ، أوقات تشغيل الخيوط وغير المترابطة). (تم التخطيط لدعم Windows وقادم قريبًا)
API Proactor. يتم تقديم العمل إلى حلقة حدث Libxev ويتم إخطار المتصل بإنجاز العمل ، بدلاً من استعداد العمل.
صفر مخصصات وقت التشغيل. يساعد هذا في جعل أداء وقت التشغيل أكثر قابلية للتنبؤ ويجعل libxev مناسبًا تمامًا للبيئات المضمنة.
أجهزة ضبط الوقت ، TCP ، UDP ، الملفات ، العمليات. واجهات برمجة تطبيقات منصة عالية المستوى من النظام الأساسي للتفاعل مع أجهزة ضبط الوقت ، ومآخذ TCP/UDP ، والملفات ، والعمليات ، وأكثر من ذلك. بالنسبة للمنصات التي لا تدعم ASYNC IO ، يتم جدولة عمليات الملف تلقائيًا في تجمع مؤشرات الترابط.
تجمع الخيط العام (اختياري). يمكنك إنشاء تجمع مؤشرات ترابط عام ، وتكوين استخدام الموارد الخاص به ، واستخدام هذا لأداء مهام الخلفية المخصصة. يتم استخدام تجمع مؤشرات الترابط من قبل بعض الخلفية للقيام بالمهام غير المحظورة التي لا تحتوي على واجهات برمجة التطبيقات غير الموثوقة غير المحظورة (مثل عمليات الملفات المحلية مع kqueue ). يمكن مشاركة مجموعة مؤشرات الترابط عبر مؤشرات ترابط متعددة وحلقات الأحداث لتحسين استخدام الموارد.
واجهة برمجة تطبيقات منخفضة المستوى وعالية المستوى. واجهة برمجة تطبيقات المستوى العالي هي المنصة العظيمة ولكن لديها بعض السلوك الرأي ومرونة محدودة. ينصح API عالي المستوى ولكن واجهة برمجة التطبيقات ذات المستوى المنخفض هي دائمًا فتحة هروب متوفرة. واجهة برمجة التطبيقات ذات المستوى المنخفض هي الخاصة بالمنصة وتوفر آلية لمستخدمي Libxev للضغط على أقصى قدر من الأداء. واجهة برمجة التطبيقات ذات المستوى المنخفض هي مجرد تجريد ما يكفي من واجهة نظام التشغيل لتسهيل استخدامه دون التضحية بالأداء ملحوظ.
هز الشجرة (متعرج). هذه سمة من سمات التعرج ، ولكنها تستفيد من المكتبات بشكل كبير مثل Libxev. ستتضمن Zig فقط مكالمات الوظائف والميزات التي تستخدمها بالفعل. إذا لم تستخدم نوعًا معينًا من مراقب المستوى العالي (مثل مآخذ UDP) ، فإن الوظيفة المتعلقة بهذا التجريد لا يتم تجميعها في ثنائي النهائي على الإطلاق. يتيح هذا لـ Libxev دعم الوظائف الاختيارية "اللطيفة إلى الحفر" التي يمكن اعتبارها "سخامًا" في بعض الحالات ، ولكن لا يتعين على المستخدم النهائي دفع ثمنها.
خالية من الاعتماد. ليس لدى Libxev أي تبعيات أخرى غير واجهات برمجة تطبيقات OS المدمجة في وقت التشغيل. مكتبة C تعتمد على libc. هذا يجعل من السهل للغاية أن يتجول.
هناك الكثير من الميزات المفقودة التي ما زلت أرغب في إضافتها:
وأكثر ...
هناك متسع كبير لتحسين الأداء ، وأريد أن أكون واضحًا تمامًا أنني لم أقم بالكثير من أعمال التحسين. ومع ذلك ، فإن الأداء يبدو جيدًا. لقد حاولت نقل العديد من معايير Libuv لاستخدام واجهة برمجة تطبيقات Libxev.
لن أنشر نتائج معيارية محددة حتى يكون لدي بيئة أفضل لتشغيلها. كتعميم واسع للغاية ، يجب ألا تلاحظ تباطؤًا باستخدام Libxev مقارنة بحلقات الأحداث الرئيسية الأخرى. قد يختلف هذا على أساس ميزة على أساس ميزة ، وإذا كان بإمكانك إظهار أداء ضعيف حقًا في مشكلة ، فأنا مهتم بحلها!
يوضح المثال أدناه برنامجًا متطابقًا مكتوبًا في Zig وفي C يستخدم libxev لتشغيل مؤقت 5s واحد. هذا أمر سخيف تقريبًا كم هو بسيط ولكن يُقصد به أن ينقل الشعور العام للمكتبة بدلاً من حالة الاستخدام العملي.
| متعرج | ج |
const xev = @import ( "xev" );
pub fn main () ! void {
var loop = try xev . Loop . init (.{});
defer loop . deinit ();
const w = try xev . Timer . init ();
defer w . deinit ();
// 5s timer
var c : xev.Completion = undefined ;
w . run ( & loop , & c , 5000 , void , null , & timerCallback );
try loop . run ( .until_done );
}
fn timerCallback (
userdata : ? * void ,
loop : * xev.Loop ,
c : * xev.Completion ,
result : xev . Timer . RunError ! void ,
) xev.CallbackAction {
_ = userdata ;
_ = loop ;
_ = c ;
_ = result catch unreachable ;
return .disarm ;
} | # include < stddef . h >
# include < stdio . h >
# include < xev . h >
xev_cb_action timerCallback ( xev_loop * loop , xev_completion * c , int result , void * userdata ) {
return XEV_DISARM ;
}
int main ( void ) {
xev_loop loop ;
if ( xev_loop_init ( & loop ) != 0 ) {
printf ( "xev_loop_init failure n " );
return 1 ;
}
xev_watcher w ;
if ( xev_timer_init ( & w ) != 0 ) {
printf ( "xev_timer_init failure n " );
return 1 ;
}
xev_completion c ;
xev_timer_run ( & w , & loop , & c , 5000 , NULL , & timerCallback );
xev_loop_run ( & loop , XEV_RUN_UNTIL_DONE );
xev_timer_deinit ( & w );
xev_loop_deinit ( & loop );
return 0 ;
} |
هذه التعليمات مخصصة للمستخدمين في اتجاه مجرى النهر فقط. إذا كنت تستخدم C API إلى Libxev ، راجع قسم "الإنشاء".
تعمل هذه الحزمة مع مدير حزمة Zig الذي تم تقديمه في Zig 0.11. إنشاء ملف build.zig.zon مثل هذا:
.{
. name = "my-project" ,
. version = "0.0.0" ,
. dependencies = .{
. libxev = .{
. url = "https://github.com/mitchellh/libxev/archive/<git-ref-here>.tar.gz" ,
. hash = "12208070233b17de6be05e32af096a6760682b48598323234824def41789e993432c" ,
},
},
} وفي build.zig :
const xev = b . dependency ( "libxev" , .{ . target = target , . optimize = optimize });
exe . addModule ( "xev" , xev . module ( "xev" ));؟ الوثائق هي عمل محرك. ؟
حاليًا ، تتوفر الوثائق في ثلاثة نماذج: صفحات الرجل والأمثلة وتعليقات التعليمات البرمجية. في المستقبل ، أخطط لكتابة أدلة مفصلة ووثائق API في شكل موقع ويب ، لكن هذا غير متوفر حاليًا.
صفحات الرجل مفصلة نسبيا! سوف يمنحك xev(7) نظرة عامة جيدة على المكتبة بأكملها. سيقدم xev-zig(7) و xev-c(7) لمحة عامة عن واجهة برمجة تطبيقات التعرج و C ، على التوالي. من هناك ، تتوفر صفحات رجل API-specifc مثل xev_loop_init(3) . هذا هو أفضل وثائق حاليا.
هناك طرق متعددة لتصفح صفحات الرجل. الأكثر ودية على الفور هو فقط تصفح مصادر صفحة Raw Man في docs/ الدليل في متصفح الويب الخاص بك. مصدر صفحة MAN هو بناء جملة يشبه التخفيضات ، لذا فإنه يجعل على ما يرام في متصفحك عبر Github.
هناك طريقة أخرى تتمثل في تشغيل zig build -Dman-pages وستتوفر صفحات MAN في zig-out . هذا يتطلب تثبيت SCDOC (هذا متاح في معظم مديري الحزم). بمجرد قيامك ببناء صفحات الرجل ، يمكنك تقديمها عن طريق المسار:
$ man zig-out/share/man/man7/xev.7
والنهج النهائي هو تثبيت libxev عبر مدير الحزمة المفضل لديك (إن كان متاحًا) ، والذي نأمل أن يضع صفحات الرجل في مسار الرجل الخاص بك ، حتى تتمكن من القيام بـ man 7 xev فقط.
هناك أمثلة متوفرة في examples/ المجلد. الأمثلة متوفرة في كل من C و Zig ، ويمكنك معرفة أي منها هو استخدام ملحق الملف.
لبناء مثال ، استخدم ما يلي:
$ zig build -Dexample-name=_basic.zig
...
$ zig-out/bin/example-basic
...
يجب أن تكون قيمة -Dexample-name هي اسم الملف بما في ذلك الامتداد.
تم التعليق بشكل جيد رمز التعرج. إذا كنت مرتاحًا لقراءة تعليقات التعليمات البرمجية ، فيمكنك العثور على الكثير من البصيرة داخلها. المصدر في src/ الدليل.
يتطلب الإنشاء تركيب أحدث ملعب ليلي. Libxev ليس لديه تبعيات أخرى للبناء.
بمجرد التثبيت ، سيقوم zig build install من تلقاء نفسه ببناء المكتبة الكاملة وإخراج دليل متوافق مع FHS في zig-out . يمكنك تخصيص دليل الإخراج باستخدام علامة --prefix .
Libxev لديه مجموعة اختبار كبيرة ومتنامية. لتشغيل اختبارات النظام الأساسي الحالي:
$ zig build test
...سيؤدي ذلك إلى تشغيل جميع الاختبارات لجميع الميزات المدعومة لمنصة المضيف الحالية. على سبيل المثال ، على Linux ، سيقوم هذا بتشغيل كل من مجموعة اختبار IO_URING الكاملة و EPOLL.
يمكنك إنشاء وتشغيل اختبارات للمنصات الأخرى عن طريق تجميع الاختبار القابل للتنفيذ ، ونسخه إلى جهاز مستهدف وتنفيذها. على سبيل المثال ، يوضح ما يلي كيفية تجميع وإنشاء اختبارات MacOS من Linux:
$ zig build -Dtarget=aarch64-macos -Dinstall-tests
...
$ file zig-out/bin/xev-test
zig-out/bin/xev-test: Mach-O 64-bit arm64 executableWasi هي حالة خاصة. يمكنك إجراء اختبارات لـ Wasi إذا كنت قد قمت بتثبيت WasmTime:
$ zig build test -Dtarget=wasm32-wasi -Dwasmtime
...