chuck-lua支持actor模式的线程模型.能够经过cthread.new
建立线程,而后经过cthread.sendmail
向线程发送消息.缓存
与skynet
这种框架不一样,chuck-lua并不提供多线程的任务/消息调度功能,每一个线程维护了一个简单的线程邮箱,用于缓存其它线程发过来的消息.安全
下面看一个简单的多线程服务器示例:服务器
mtserver.lua多线程
local chuck = require("chuck") local engine = require("distri.engine") local socket_helper = chuck.socket_helper local Distri = require("distri.distri") local cthread = chuck.cthread local worker function on_new_client(fd) cthread.sendmail(worker,{fd}) end local fd = socket_helper.socket(socket_helper.AF_INET, socket_helper.SOCK_STREAM, socket_helper.IPPROTO_TCP) socket_helper.addr_reuse(fd,1) local ip = "127.0.0.1" local port = 8010 if 0 == socket_helper.listen(fd,ip,port) then print("server start",ip,port) local server = chuck.acceptor(fd) server:Add2Engine(engine,on_new_client) Distri.Signal(chuck.signal.SIGINT,Distri.Stop) worker = cthread.new("distri/test/worker.lua") Distri.Run() end
worker.lua框架
local chuck = require("chuck") local socket = require("distri.socket") local engine = require("distri.engine") local clone = chuck.packet.clone local cthread = chuck.cthread local Distri = require("distri.distri") --设置邮件处理函数 cthread.process_mail(engine,function (sender,mail) local fd = table.unpack(mail) local s = socket.stream.New(fd) if s:Ok(4096,socket.stream.decoder.rawpacket(),function (_,msg,errno) if msg then s:Send(clone(msg)) else s:Close(errno) s = nil end end) then s:SetRecvTimeout(5000) else s:Close() end end) Distri.Run()
这个示例很简单,主线程启动监听,建立一个线程,当接收到链接时就将fd发送给worker线程.socket
在这里须要简单介绍一下chuck-lua线程相关的一些细节.函数
由于各线程跑在独立的虚拟机上,所以没法直接经过消息的方式将一个虚拟机中的对象发送到另外一个线程中.目前sendmail将做为消息传递给它的lua table序列化为一种适合传输的对象,目标线程接收这个对象以后再从新转化成本线程虚拟机中的lua table.目前消息支持lua中的全部基本类型,但为了安全考虑,不支持直接传递userdata类型.ui
用cthread.sendmail
向目标线程发送消息时,若是到达目标邮箱的缓冲上线将会阻塞.全部指望处理邮件消息的线程都必须调用cthread.process_mail
设定消息回调函数.若是不设定,将可能致使消息发送线程永久阻塞.lua
线程使用join模式建立,建立者能够经过cthread.join
等待线程的结束.线程