北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
查看: 6648|回复: 5

Cmud时间控制再探索

[复制链接]
发表于 2010-2-7 15:07:14 | 显示全部楼层 |阅读模式
时间控制是编写一个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本身都无法保证,因为你还要加
上服务器来回传递命令的时间。用服务器来保证时间延时还有一个好处就是当网速慢的时候
他延时自然就变长了,不会早于服务器发出命令。当然我这里不怎么提倡用这一手段编程,
毕竟这样做会对服务器造成额外负担。实际上跳楼、区域搜索的时候这一手段是保持高效
的唯一手段,其他延时都太慢了。

评分

参与人数 1精华 +30 收起 理由
icer + 30

查看全部评分

北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2010-2-7 16:01:41 | 显示全部楼层
很好,再接再砺
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2010-2-7 16:03:26 | 显示全部楼层
#alarm 可以和%alarm结合起来,创建复杂的alarm
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2010-2-7 23:27:36 | 显示全部楼层
顶上去,希望看到更多这样的帖子!
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2010-2-9 11:33:21 | 显示全部楼层
发现个很严重的问题,我还不知道%和#什么区别,汗,要多看看帮助了
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2010-2-9 23:53:27 | 显示全部楼层
%是函数,#是命令,就这个区别。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-25 07:51 AM , Processed in 0.010316 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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