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
等待線程的結束.線程