用户工具

站点工具


cmud:timer:cmud时间控制再探索

Cmud时间控制再探索

出品人:Seagate

原帖地址:Cmud时间控制再探索

时间控制是编写一个mud机器人最大的挑战,一个机器人时间控制的好差绝定了这个机器人是否高效,是否稳定等等。前些日子写过一个简单的心得体会贴,那时候刚用 cmud不久,很多原理方面的东西没有做很深的探索,这里再发一贴谈谈更深入一点的 东西。

在cmud里面用zscript编程的前提下对时间控制大体上有三种技巧,第一种是用tick timer 计时器,第二种是用wait系列命令,第三种是用#alarm触发器。这三种还是有区别的, tick timer计时器是最稳定的,这个是cmud程序保证的一个独立计时器,基本上是独立于 主进程之外的,主进程的运行环境很难影响到tick timer的运行环境,你可以改变tick timer 计时器的执行命令,时间间隔,但是他起效果的时候是在什么样的环境发生的你一般来说 是很难修改了。这在cmud多线程环境中非常关键,由于多线程环境一般来说可以同一个 session可以同时运行多个环境,环境的稳定性对程序的稳定性是一个致命的挑战。我个人 感觉编写cmud程序90%的精力差不多都用在保证触发前后环境是否一致上。这一点往往是 很难保证的,从这一点来看tick timer的难得可贵了。可惜的是一个session你无法控制多个 tick timer,这个东东只能作为计时、冗灾等用途。最好不要将tick timer计时器用作更广泛 的用户。一般定时触发还是交给#wait和#alarm两种手段来执行吧。

#wait系列包括#wait、#waitsignlal、#waitthread三种命令,实际上原理都是一样的,这 些命令的作用原理是,当你发出#wait命令的时候,主线程会挂起,然后cmud会起一个wait 的子线程,子线程执行到规定秒数或者规定条件获得以后子线程结束,主线程重新获得心跳。 #wait命令的不稳定在于子线程结束切换到主线程的这一过程中,比如#wait 500,主线程有 可能在挂起的500毫秒中来了对多个windows的处理触发,这时候你挂起前的环境就有可能 切换不到你想要的windows上,这时候错误就发生了。我举例一个场景吧:

    触发1:A 
    命令1:cmd1;#wa 500;cmd2
    触发2:【闲聊】张三来了
    命令2:#cap important;#gag

当执行完cmd1,#wait的500毫秒的过程中服务器发出了一个闲聊命令,在#wait结束的时候 就 会同时要执行#cap important和cmd2两个命令,这个时候你就不知道你的cmd2是否一定 会在主窗口上执行了。如果你的cmd2有给全局变量赋值之类东东或者起#alarm之类就不知 道这些玩意会在哪个windows上发生作用,更致命的是如果你是起com object有可能就会发 生更多的不可预料的事情。这个问题发生的关键在于#wait命令影响了正常命令的执行环境。 所以关键点在于如果你的执行环境中有非常复杂的命令最好不要用#wait来控制时间,当然 简单的alias中是一点问题也没有的。

#alarm触发器是另外一种模式的定时,当你起用#alarm触发器的时候,他会把触发器中 的命令放到一个新建的线程中执行。所以#alarm触发器不会产生#wait那种影响主线程环境 的情况发生,用好#alarm触发器比#wait会更稳定也在于这一点。但是有一个问题在于由于 #alarm触发器是另起一个线程执行命令,那么你当前线程中预设的local变量就传递不进 #alarm触发器了,要传递变量只能通过全局变量来传递。这一点就没有#wait来的好了。还 有一点由于是多线程环境难免#alarm会受到其他变更主线程环境的多线程命令影响导致执 行环境出现变更使得#alarm结果失效,这一点虽然发生概率很低但是确实会发生,记住不 要把#alarm当成一定不会出事的东西就行,肯定不会出事的只有tick timer。

#alarm还有一个麻烦的地方在于当你要执行多个定时的时候就很麻烦,比如#wait命令中 很简单的cmd1;#wa 500;cmd2;#wa 500;cmd3你要用#alarm写就很麻烦,而且你会 感觉到忐忑不安。#alarm写法就是cmd1;#alarm +0.5 {cmd2;#alarm +0.5 {cmd3}}。至少 我从来没这么写过,碰到这种情况还是给#wa解决吧,或者自己处理的时候用其他方式解 决掉他,比如用服务器守护的形式。

服务器守护这是另外一种定时方式,有时候你确实需要一个延时,但是延时需要高效安 全的,那么你可以给服务器发一个命令,然后你自己用接收到的返回字符串执行命令, 延时完全由你传递到服务器到服务器返回信息的时间差来决定,网速快的时候最多只会延时 低于50毫秒,小于100毫秒的定时一般来说#alarm和#wait本身都无法保证,因为你还要加 上服务器来回传递命令的时间。用服务器来保证时间延时还有一个好处就是当网速慢的时候 他延时自然就变长了,不会早于服务器发出命令。当然我这里不怎么提倡用这一手段编程, 毕竟这样做会对服务器造成额外负担。实际上跳楼、区域搜索的时候这一手段是保持高效 的唯一手段,其他延时都太慢了。

cmud/timer/cmud时间控制再探索.txt · 最后更改: 2020/08/15 21:40 (外部编辑)