Skynet協同模型

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章