--Lua脚本
function f1()
for i=1,5 do
delay(1000)
setCaption('脚本1 '..i )
end
setCaption('脚本1 结束')
end
function f2()
for i=1,5 do
delay(2000)
setCaption('脚本2 '..i )
end
setCaption('脚本2 结束')
end
function f3()
for i=1,5 do
delay(3000)
setCaption('脚本3 '..i )
end
setCaption('脚本3 结束')
end
co1=coroutine.create(f1)
co2=coroutine.create(f2)
co3=coroutine.create(f3)
coroutine.resume(co1)
coroutine.resume(co2)
coroutine.resume(co3)
运行结果
脚本1 1
脚本1 2
脚本2 1
脚本1 3
脚本3 1
脚本1 4
脚本2 2
脚本1 5
脚本1 结束
脚本2 3
脚本3 2
脚本2 4
脚本3 3
脚本2 5
脚本2 结束
脚本3 4
脚本3 5
脚本3 结束
实现原理
在主函数中为每个函数(f1,f2,f3)创建一个协程(co1,co2,co3)
在脚本中调用函数Delay时, 设置了一个定时器, 调用Yield把脚本挂起
当定时器时间到时, 调用Resume再恢复脚本的运行,
协程co1,co2,co3在运行到delay这个函数时,都会挂起自已,
让其它协程有机会获得执行权
任何时候最多只有1个协程是在运行的
但看起来就象是同时运行在运行函数f1,f2,f3
宿主程序中的代码(Delphi)如下
var
LuaTimerList:Tlist;
procedure LuaTimerProc(hWnd: HWND; uMsg: UINT; idEvent: UINT; Time: DWORD);stdcall;
var
i:integer;
id:UINT;
LuaState: TLuaState;
begin
killtimer(hwnd,idEvent);
for i:=(LuaTimerList.Count div 2) -1 downto 0 do begin
id:=UINT(LuaTimerList.Items[i*2+1]);
if id=idEvent then begin
LuaState:=TLuaState(LuaTimerList[i*2]);
LuaTimerList.Delete(i*2+1);
LuaTimerList.Delete(i*2);
lua_resume(LuaState,0);
end;
end;
end;
function TTestLua.delay(LuaState: TLuaState): Integer;
var
milliseconds:integer;
id:integer;
begin
if Lua_Gettop(LuaState)=0 then exit;
milliseconds := Lua_ToInteger(LuaState,1);
id := settimer(0,0,milliseconds,@LuaTimerProc);
if LuaTimerList=nil then LuaTimerList := TList.create;
LuaTimerList.Add(pointer(LuaState));
LuaTimerList.Add(pointer(id));
//登记一下定时器ID对应的Lua实例
result:=Lua_Yield(LuaState,0);
end;
[课程]Linux pwn 探索篇!