源文件:lualib/skynet.lua
skynet中对协同程序的应用
一、启动
//1. skynet.start(start_func)
function skynet.start(start_func)
c.callback(dispatch_message) // 注册回调函数
skynet.timeout(0, function() // 提交msg给线程执行(被执行时,会调用上一步注册的回调函数(dispatch_message)执行)
init_service(start_func) // 需被执行函数
end)
end
//2. skynet.timeout(ti, func)
function skynet.timeout(ti, func)
local session = c.command("TIMEOUT", tostring(ti)) // 每次调用都分配一个新的session(不重复) 并调用线程执行
local co = co_create(func) // 创建新的协同程序
session_id_coroutine[session] = co // 存储session的co
end
//3. co_create(f)
function co_create(f)
...
co = coroutine.create(function(...)
f(...) // 先执行一次
while true do -- 循环执行
f = nil // nil
coroutine_pool[#coroutine_pool+1] = co // 加入线程池
f = coroutine_yield "EXIT" // 阻塞(一个方法执行结束,等待下一个方法)
f(coroutine_yield()) // 执行下一个方法(疑问)
end
end)
...
end
二、执行
//1. dispatch_message(...)
function dispatch_message(...)
local succ, err = pcall(raw_dispatch_message, ...)
...
end
//2. raw_dispatch_message
function raw_dispatch_message(prototype, msg, sz, session, source, ...)
if prototype == 1 then
local co = session_id_coroutine[session]
if co == "BREAK" then
session_id_coroutine[session] = nil
elseif co == nil then
unknown_response(session, source, msg, sz)
else
session_id_coroutine[session] = nil // 清空此session的线程
suspend(co, coroutine.resume(co, true, msg, sz)) // 调用coroutine.resume(co, true, msg, sz)调用co_create主函数
end
else
...
en
end
3. co_create
co = coroutine.create(function(...)
f(...) // 第一次执行用 init_service(start_func)
while true do // 循环执行
f = nil // nil
coroutine_pool[#coroutine_pool+1] = co // 加入线程池
f = coroutine_yield "EXIT" // 阻塞(一个方法执行结束,等待下一个方法) 至此为止 完成了第一次的协同调用
f(coroutine_yield()) // 执行下一个方法
end
end)