Libxev เป็นลูปเหตุการณ์ข้ามแพลตฟอร์ม Libxev จัดเตรียมเหตุการณ์ที่เป็นนามธรรมแบบรวมสำหรับ IO ที่ไม่ปิดกั้นตัวจับเวลาสัญญาณเหตุการณ์และอื่น ๆ ที่ทำงานบน MacOS, Windows, Linux และ WebAssembly (เบราว์เซอร์และ WASI) มันถูกเขียนขึ้นในซิก แต่ส่งออก API ที่เข้ากันได้กับ C (ซึ่งทำให้เข้ากันได้กับภาษาใด ๆ ที่สามารถสื่อสารกับ C API)
สถานะโครงการ:? คุณภาพที่ไม่เสถียรอัลฟ่า-อิช รายการคุณสมบัติค่อนข้างดีในหลายแพลตฟอร์ม แต่มีคุณสมบัติที่ขาดหายไปมากมาย โครงการยังไม่ได้รับการทดสอบอย่างดีในสภาพแวดล้อมในโลกแห่งความเป็นจริงและมีผลไม้แขวนลอยต่ำจำนวนมากสำหรับการเพิ่มประสิทธิภาพประสิทธิภาพ ฉันไม่ได้สัญญาความเข้ากันได้ของ API ใด ๆ ณ จุดนี้เช่นกัน หากคุณต้องการให้การผลิตพร้อมคุณภาพสูงการใช้งานลูปเหตุการณ์ทั่วไปตรวจสอบ libuv, libev ฯลฯ
ทำไมต้องเป็นห้องสมุด Event Loop ใหม่? เหตุผลบางประการ หนึ่งฉันคิดว่า Zig ขาดลูปเหตุการณ์ทั่วไปเทียบเท่ากับ libuv ในคุณสมบัติ ("ทั่วไป" เป็นคำสำคัญที่นี่) สองฉันต้องการสร้างห้องสมุดเช่นนี้รอบ ๆ รูปแบบการออกแบบของ io_uring แม้กระทั่งการเลียนแบบสไตล์ของมันในด้านบนของระบบระบบปฏิบัติการอื่น ๆ (เครดิตกับโพสต์บล็อกที่ยอดเยี่ยมนี้) สามฉันต้องการห้องสมุด Event Loop ที่สามารถสร้างไปยัง WebAssembly (ทั้ง Wasi และ Freestanding) และนั่นก็ไม่เหมาะกับเป้าหมายของสไตล์ API ของห้องสมุดที่มีอยู่โดยไม่ต้องนำสิ่งที่หนักมากเหมือน emscripten แรงจูงใจสำหรับห้องสมุดนี้เป็นหลักแม้ว่าจะเป็นรอยขีดข่วนของฉันเอง!
ข้ามแพลตฟอร์ม Linux ( io_uring และ epoll ), macOS ( kqueue ), webAssembly + wasi ( poll_oneoff , treaded และ non-threaded runtimes) (มีการวางแผนการสนับสนุน Windows และเร็ว ๆ นี้)
Proactor API งานจะถูกส่งไปยัง Libxev Event Loop และผู้โทรได้รับแจ้งถึงการทำงาน ให้เสร็จสิ้น เมื่อเทียบกับ ความพร้อมใน การทำงาน
การจัดสรรรันไทม์เป็นศูนย์ สิ่งนี้จะช่วยให้ประสิทธิภาพการทำงานของรันไทม์คาดการณ์ได้มากขึ้นและทำให้ Libxev เหมาะสำหรับสภาพแวดล้อมที่ฝังตัว
ตัวจับเวลา, TCP, UDP, ไฟล์, กระบวนการ APIs แพลตฟอร์มระดับสูงสำหรับการโต้ตอบกับตัวจับเวลาซ็อกเก็ต TCP/UDP ไฟล์กระบวนการกระบวนการและอื่น ๆ สำหรับแพลตฟอร์มที่ไม่รองรับ Async IO การดำเนินการไฟล์จะถูกกำหนดไว้โดยอัตโนมัติเป็นพูลเธรด
พูลเธรดทั่วไป (ไม่บังคับ) คุณสามารถสร้างพูลเธรดทั่วไปกำหนดค่าการใช้ทรัพยากรและใช้สิ่งนี้เพื่อทำงานพื้นหลังที่กำหนดเอง พูลเธรดถูกใช้โดยแบ็กเอนด์บางส่วนเพื่อทำงานที่ไม่ปิดกั้นซึ่งไม่มี API ที่ไม่น่าเชื่อถือ (เช่นการดำเนินงานไฟล์ท้องถิ่นกับ kqueue ) พูลเธรดสามารถแชร์ได้หลายเธรดและลูปเหตุการณ์เพื่อเพิ่มประสิทธิภาพการใช้ทรัพยากร
API ระดับต่ำและระดับสูง API ระดับสูงเป็นแพลตฟอร์มที่ไม่เชื่อเรื่องพระเจ้า แต่มีพฤติกรรมที่มีความเห็นและมีความยืดหยุ่น จำกัด แนะนำ API ระดับสูง แต่ API ระดับต่ำจะเป็นฟักหลบหนีที่มีอยู่เสมอ API ระดับต่ำเป็นแพลตฟอร์มที่เฉพาะเจาะจงและเป็นกลไกสำหรับผู้ใช้ Libxev เพื่อบีบประสิทธิภาพสูงสุด API ระดับต่ำนั้นเป็น สิ่งที่เป็นนามธรรมเพียงพอ เหนืออินเทอร์เฟซ OS เพื่อให้ใช้งานได้ง่ายขึ้นโดยไม่ต้องเสียสละประสิทธิภาพที่เห็นได้ชัดเจน
การเขย่าต้นไม้ (ซิก) นี่เป็นคุณสมบัติของซิก แต่เป็นประโยชน์ต่อห้องสมุดอย่างมากเช่น Libxev ZIG จะรวมเฉพาะการเรียกใช้ฟังก์ชั่นและคุณสมบัติที่คุณใช้จริง หากคุณไม่ได้ใช้ผู้เฝ้าดูระดับสูงชนิดใดประเภทหนึ่ง (เช่นซ็อกเก็ต UDP) ฟังก์ชั่นที่เกี่ยวข้องกับนามธรรมนั้นไม่ได้รวบรวมไว้ในไบนารีสุดท้ายของคุณเลย สิ่งนี้ช่วยให้ Libxev รองรับฟังก์ชั่น "Nice-to-have" ที่เป็นตัวเลือกซึ่งอาจได้รับการพิจารณาว่า "bloat" ในบางกรณี แต่ผู้ใช้ไม่ต้องจ่ายเงิน
ปราศจากการพึ่งพา Libxev ไม่มีการพึ่งพานอกเหนือจาก OS APIs ในตัวที่รันไทม์ ห้องสมุด C ขึ้นอยู่กับ LIBC ทำให้ง่ายต่อการแข่งขันข้าม
มีคุณสมบัติที่ขาดหายไปมากมายที่ฉันยังต้องการเพิ่ม:
และอีกมากมาย ...
มีพื้นที่มากมายสำหรับการปรับปรุงประสิทธิภาพและฉันต้องการชัดเจนว่าฉันไม่ได้ทำงานเพิ่มประสิทธิภาพมากมาย ถึงกระนั้นประสิทธิภาพก็ดูดี ฉันได้พยายามพอร์ตเกณฑ์มาตรฐาน Libuv จำนวนมากเพื่อใช้ Libxev API
ฉันจะไม่โพสต์ผลลัพธ์มาตรฐานเฉพาะจนกว่าฉันจะมีสภาพแวดล้อมที่ดีกว่าในการเรียกใช้พวกเขาใน ฐานะทั่วไปที่กว้างมาก คุณไม่ควรสังเกตการชะลอตัวโดยใช้ Libxev เมื่อเทียบกับลูปเหตุการณ์สำคัญอื่น ๆ สิ่งนี้อาจแตกต่างกันไปตามคุณสมบัติตามคุณสมบัติและหากคุณสามารถแสดงประสิทธิภาพที่ไม่ดีในปัญหาฉันสนใจที่จะแก้ไขมัน!
ตัวอย่างด้านล่างแสดงโปรแกรมที่เหมือนกันที่เขียนใน zig และใน C ที่ใช้ Libxev เพื่อเรียกใช้ตัวจับเวลา 5S เดี่ยว นี่เกือบจะโง่แค่ไหนที่มันง่าย แต่มีความหมายเพียงแค่ถ่ายทอดความรู้สึกโดยรวมของห้องสมุดมากกว่ากรณีการใช้งานจริง
| ซิก | C |
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 ให้ดูที่ส่วน "build"
แพ็คเกจนี้ใช้งานได้กับ Zig Package Manager ที่แนะนำใน 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) จะให้ภาพรวมของ ZIG และ C API ตามลำดับ จากนั้นจะมีหน้า API-specifc เช่น xev_loop_init(3) นี่คือเอกสารที่ดีที่สุดในปัจจุบัน
มีหลายวิธีในการเรียกดูหน้าผู้ชาย สิ่งที่เป็นมิตรที่สุดในทันทีคือเพียงแค่เรียกดูแหล่งข้อมูลหน้าดิบใน docs/ ไดเรกทอรีในเว็บเบราว์เซอร์ของคุณ แหล่งที่มาของ Man Page เป็นไวยากรณ์ คล้าย markdown ดังนั้นจึงแสดง ผล ในเบราว์เซอร์ของคุณผ่าน 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 ควรเป็นชื่อไฟล์รวมถึงส่วนขยาย
รหัส ZIG มีความคิดเห็นที่ดี หากคุณสะดวกสบายในการอ่านความคิดเห็นของรหัสคุณสามารถหาข้อมูลเชิงลึกมากมายภายใน แหล่งที่มาอยู่ในไดเรกทอรี src/
Build ต้องการการติดตั้งซิกล่าสุดทุกคืน Libxev ไม่มีการพึ่งพาการสร้างอื่น ๆ
เมื่อติดตั้งแล้ว zig build install ด้วยตัวเองจะสร้างไลบรารีเต็มรูปแบบและส่งออกไดเรกทอรีที่เข้ากันได้กับ FHS ใน zig-out คุณสามารถปรับแต่งไดเรกทอรีเอาต์พุตด้วย --prefix FLAG
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
...