libxev是一个跨平台事件循环。 Libxev为非块IO,计时器,信号,事件等提供了一个统一的事件循环抽象,可用于MACOS,Windows,Linux和WebAssembly(浏览器和WASI)。它是用Zig编写的,但导出了C兼容CAPI(这进一步使其与可以与C API通信的任何语言兼容)。
项目状态:?不稳定,α-质量。在多个平台之间,功能列表非常好,但是有很多缺少的功能。该项目在现实世界环境中的测试尚未得到很好的测试,并且有许多低调的水果以进行性能优化。在这一点上,我也不承诺任何API兼容性。如果您想准备制作,高质量,广泛的事件循环实施,请查看Libuv,Libev等。
为什么要有一个新的活动循环库?一些原因。第一,我认为Zig缺乏与libuv在功能中相当的广义事件循环(在这里,“广义”是关键词)。第二,我想围绕io_uring的设计模式构建这样的库,甚至在其他OS原始图中模仿其风格(归功于这篇很棒的博客文章)。第三,我想要一个活动循环库,它可以构建为WebAssembly(Wasi和独立式),并且它并不符合现有库的API风格的目标,而不会带来像Emscripten这样的超重内容。这个图书馆的动机主要是在挠我的痒!
跨平台。 linux( io_uring和epoll ),macos( kqueue ),webAssembly + wasi( poll_oneoff ,螺纹和非线程运行时间)。 (计划支持Windows支持,并即将推出)
procractor api。工作已提交给Libxev事件循环,并通知呼叫者工作完成,而不是工作准备。
零运行时分配。这有助于使运行时性能更具可预测性,并使Libxev非常适合嵌入式环境。
计时器,TCP,UDP,文件,进程。用于与计时器,TCP/UDP插座,文件,进程等相互作用的高级平台-Nostic API。对于不支持异步IO的平台,将自动安排到线程池。
通用线程池(可选)。您可以创建一个通用线程池,配置其资源利用率,并使用它执行自定义背景任务。某些后端使用线程池来执行没有可靠的非阻止API的非阻滞任务(例如带有kqueue的本地文件操作)。可以通过多个线程和事件循环共享线程池以优化资源利用率。
低级和高级API。高级API是平台不可静止的,但具有一些自以为是的行为和有限的灵活性。建议使用高级API,但低级API始终是可用的逃生舱口。低级API是平台特定的,为Libxev用户提供了一种机制,可以挤出最高性能。低级API在OS接口上方足够的抽象,以使其在不牺牲明显性能的情况下更易于使用。
树木摇动(Zig)。这是Zig的一个特征,但基本上有益于Libxev等库。 Zig仅包括您实际使用的功能调用和功能。如果您不使用特定类型的高级观察者(例如UDP插座),那么与该抽象相关的功能根本根本不会汇总到您的最终二进制中。这使Libxev支持可选的“尼斯 - 距离”功能,在某些情况下可能被视为“膨胀”,但最终用户不必为此付费。
无依赖。除了运行时内置的OS API以外,Libxev没有其他依赖项。 C库取决于LIBC。这使得跨编译非常容易。
我仍然想添加很多缺少的功能:
还有更多...
有足够的绩效改进空间,我想完全清楚我没有做很多优化工作。尽管如此,性能还是很好。我试图将许多Libuv基准测试用于使用Libxev API。
在我有更好的环境可以运行的环境之前,我不会发布特定的基准结果。作为一个非常广泛的概括,与其他主要事件循环相比,使用Libxev使用Libxev会有所放缓。这可能会在逐个功能的基础上有所不同,如果您能在我有兴趣解决的问题中表现出非常差的性能!
下面的示例显示了使用Zig和C中编写的相同程序,该程序使用Libxev运行单个5S计时器。这几乎是愚蠢的,但是只是为了传达图书馆的整体感觉而不是实际的用例。
| ZIG | 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,请参见“构建”部分。
该软件包可与Zig 0.11中引入的ZIG软件包管理器一起使用。创建一个类似的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的概述。从那里,可以使用API-Specifc Man页面,例如xev_loop_init(3) 。这是当前最好的文档。
有多种浏览人页面的方法。最立即友好的是只需在网络浏览器中的docs/目录中浏览Raw Man页面源即可。 Man Page源是一种类似Markdown的语法,因此它可以通过GitHub在浏览器中呈现。
另一种方法是运行zig build -Dman-pages ,并且该页面将在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/目录中。
构建需要每晚安装最新的Zig。 Libxev没有其他构建依赖性。
安装后, zig build install将构建完整的库,并在zig-out中输出一个与FHS兼容的目录。您可以使用--prefix标志自定义输出目录。
Libxev拥有一个大型且增长的测试套件。为当前平台运行测试:
$ zig build test
...这将对当前主机平台的所有支持功能运行所有测试。例如,在Linux上,这将同时运行完整的io_uring和Epoll Test Suite。
您可以通过对测试可执行文件进行交叉编译,将其复制到目标计算机并执行它来构建和运行其他平台的测试。例如,以下显示了如何跨编译和从Linux构建MacOS的测试:
$ zig build -Dtarget=aarch64-macos -Dinstall-tests
...
$ file zig-out/bin/xev-test
zig-out/bin/xev-test: Mach-O 64-bit arm64 executableWasi是一个特殊情况。如果您安装了WASMTIME,则可以对WASI进行测试:
$ zig build test -Dtarget=wasm32-wasi -Dwasmtime
...