北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
楼主: muxiao

请教这个mush的alias问题

[复制链接]
发表于 2009-5-31 18:56:30 | 显示全部楼层
yield挂起当前所在代码段的 thread
设计思路是先起 递归 thread (2),然后yield当前 thread (1),等递归(2)结束,再resume(1)

问题出现在yield的执行时间点是不可控的,所以可能出现如下状态:
先进入递归,调用 resume (2),但是没有继续执行(1),即没有 yield(1)而是沿着(2)继续运行,直到(2)结束。
此时认为递归(2)结束,应返回(1),于是resume(1),但(1)的 yield 语句尚未执行,当继续执行 yield(1)时,从(2)返回的resume(1)已经执行过,没有其他部分可以激活 (1)
所以,死在(1)的 yield 语句
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2009-5-31 18:59:31 | 显示全部楼层
俺头一回见识coroutine,不知道有没有同步机制,类似synchronize的
用最笨的,外层递归轮循监视内层递归是否完成,若完成则继续,否则等待
这已经离所谓的并发越来越远了。。。囧

taoyuan,beijing,huyidao,wudang测试通过
temp_thread_path = {}
function exec_alias(s)
temp_thread_path=coroutine.create(function (s)
   Note ("create coroutine : ", s)
   local p_temp = Split(s,";");
   for i,v in ipairs(p_temp) do
    if alias_table[v] then
     exec_alias (alias_table[v], s)
     Note ("before yield")
     while temp_thread_path[alias_table[v]] do
      Note ("before yield ", temp_thread_path[alias_table[v]])
      DoAfterSpecial (1, "resume_coroutine(\""..s.."\")", 12)
      coroutine.yield ()
     end

    elseif nil~=string.find(v,"#%d+ ") then
     world.Send(do_table[string.sub(v,string.find(v,"#%d+ "))]..string.sub(v,string.find(v," .+")));
    elseif nil~=string.find(v,"#wa") then  
     world.DoAfterSpecial(string.sub(v,string.find(v,"%d+")) / 2000,"resume_coroutine(\""..s.."\")",12);
     coroutine.yield();
    else
     world.Send(v);
    end
   end
   Note ("coroutine end : ", s)
   temp_thread_path = nil
end)
coroutine.resume(temp_thread_path,s);
end
function resume_coroutine (thread_name)
Note ("resume_coroutine : ", thread_name)
coroutine.resume(temp_thread_path[thread_name]);
end

[ 本帖最后由 duno 于 2009-5-31 07:01 PM 编辑 ]
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2009-5-31 19:30:25 | 显示全部楼层
yield出没,请注意!
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2009-5-31 19:32:30 | 显示全部楼层
coroutine里可以加入wait.time(),以控制时间。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2009-5-31 20:53:34 | 显示全部楼层
实际核对了一遍table的数据,只有以下5个是既有路径alias又有#wa的:

gumu
taoyuan
tiandihui
guiquan
xiangyang

针对这个问题,最简单的办法还是回到table里,用真实路径字符串替代那5个alias……


不过,另一面,很难的看到LUA的coroutine的实际应用,研究一下,也涨不少知识呢……
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2009-5-31 20:59:22 | 显示全部楼层
确实偏离了,还没测试这段代码.呵呵.
等吃过饭分析一下,并不一定死在挂起操作上,简单问题复杂化.
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2009-5-31 21:42:34 | 显示全部楼层
找到一个gammon关于coroutine的例子,估计是这个plugin的原型

http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=4956
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2009-5-31 21:48:02 | 显示全部楼层
wait.lua的功能很强大啊,貌似不用coroutine了……
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2009-5-31 22:17:49 | 显示全部楼层
好复杂啊,要慢慢看!
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2009-5-31 22:18:15 | 显示全部楼层
俺认为这里yield的问题是并发控制和原子性操作的问题,靠指定挂起等待时间不能完全解决
resume(2)和yield(1)两步在thread(1)中应该是不可分的

wait.lua是在模拟#wa的功能
在防止指令太快服务器不响应方面,#wa功能可以通过Execute的Delay代替,delay比#wa更简洁
wait.lua的应用举例也说得是各种有busy操作之间连贯和衔接,“all that achieves is to "hang" the entire PC for a while”
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|北大侠客行MUD ( 京ICP备16065414号-1 )

GMT+8, 2024-11-24 10:12 PM , Processed in 0.010674 second(s), 13 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表