libuv 是大名鼎鼎的 nodejs 的底层库。用 C 实现,代码量不大,但是五脏俱全。比起同类项目 libevent 我更喜欢它简洁的 API 接口。比 libevent 少了 httpserver 多了 subprocess 功能,封装得很棒,免去了传统的 fork 和 pipe 的不直观的做法。
lua 可以说是流行的脚本语言中:功能较强、代码最少、性能较高、逼格非常高的脚本语言。设计得很优雅,关键字很少,这点和 golang 的思路很像。与 C 之间有可定制型极强的 API 交互接口。其实就是完全暴露了整个 lua 虚拟机的接口,可以自行构造任意的 lua 代码和数据结构,极其强大好用。
这两个项目结合在一起,是很有意思的。本质上相当于一个小型的 v8,lua 和 javascript 的特性还是挺像的。在不涉及大量复杂运算,只是想用脚本的语言的特性做点快速开发的时候。这个组合是性价比相当高的。即便是涉及大量运算,也可以选用 luajit,评测中它的大部分指标已经超过 v8 了。
把他们俩结合的时候,有一些爽点和坑点如下:
- libuv 凡是 handle 类型必须要调用 uv_close 关闭。不然会造成内存泄露。
- lua 和 C 的交互都是通过堆栈操作来进行的,和汇编有点像,一开始很容易弄错参数位置,比较好的办法是使用 pcall,在崩溃的时候打印出 traceback 和 stackinfo。
- 在最外层 uv_loop 中调用 lua 的时候,必须以调用一个 lua 函数开始。不然弄错了参数个数就内存泄露了。lua 函数默认是有保护的,弄错了也没问题。
- 灵活的使用 lua 中的 userdata 可以搞很多有意思的事情。比如说某个底层 C 模块获取了一个很大的 buffer,交给另外一个底层 C 模块处理