duno 发表于 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 语句

duno 发表于 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 then
   exec_alias (alias_table, s)
   Note ("before yield")
   while temp_thread_path] do
      Note ("before yield ", temp_thread_path])
      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," .+")));
    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);
end


[ 本帖最后由 duno 于 2009-5-31 07:01 PM 编辑 ]

ddid 发表于 2009-5-31 19:30:25

yield出没,请注意!

ddid 发表于 2009-5-31 19:32:30

coroutine里可以加入wait.time(),以控制时间。

ddid 发表于 2009-5-31 20:53:34

实际核对了一遍table的数据,只有以下5个是既有路径alias又有#wa的:

gumu
taoyuan
tiandihui
guiquan
xiangyang

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


不过,另一面,很难的看到LUA的coroutine的实际应用,研究一下,也涨不少知识呢……

muxiao 发表于 2009-5-31 20:59:22

确实偏离了,还没测试这段代码.呵呵.
等吃过饭分析一下,并不一定死在挂起操作上,简单问题复杂化.

ddid 发表于 2009-5-31 21:42:34

找到一个gammon关于coroutine的例子,估计是这个plugin的原型

http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=4956

ddid 发表于 2009-5-31 21:48:02

wait.lua的功能很强大啊,貌似不用coroutine了……

maper 发表于 2009-5-31 22:17:49

好复杂啊,要慢慢看!

duno 发表于 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”
页: 1 2 3 4 [5] 6
查看完整版本: 请教这个mush的alias问题