最近在学习go,对go中网络处理的方式比较喜欢,就用lua coroutine + C 模仿着接口实现一个玩具玩玩.
主要框架是lua导入C模块的时候会启动一个网络线程,lua和网络之间通过两个消息队列交互,lua将网络请求通过消息队列发送到C,
C将应答和网络事件通过消息队列发送到lua.
lua主线程运行在一个coroutine调度循环上,并不断的尝试从队列获得消息,一但收到消息就唤醒等待在此消息上阻塞的lua coroutine.
跟go的区别是,go routine是可以在多个处理器核心上运行的.
我在设计的时候也考虑过,是否将spwan函数也实现成多线程的,程序启动的时候开N个线程创建N个虚拟机跑coroutine调度器,spwan的
时候将这个创建请求分发到负载最轻的coroutine调度线程上 。但lua虚拟机之间传递数据并不是这么方便,实现起来也不是那么clean,所以
暂时放弃了这个念头.
下面贴一段nodelua的tcp echo服务示例:
require("nodelua") dofile("node/scheduler.lua") function doio(s) print("doio") while true do local data,err = s:recv() if err == "disconnected" then print("a socket disconnect") return else s:send(data) end end end function listen_fun(l) print("listen_fun") while true do local s,err = l:accept() if s then node_spwan(s,doio) --spwan a light process to do io elseif err == "stop" then return end end end function main() --local l,err = tcp_listen("127.0.0.1",8010)--arg[1],arg[2]) local l,err = tcp_listen(arg[1],arg[2]) if err then print("listen error") return end print("listen ok") if l then node_spwan(l,listen_fun) --spwan a light process to do accept end node_loop() print("see you!") end main()
目前nodelua只实现了对tcp的支持,还不完善,后续会慢慢完善.