源文件: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)