seagate 发表于 2010-4-18 11:31:31

Cmud时间控制再揭秘

这一次主要说说系统稳定性稳定,实际上90%的系统稳定性源头都在于时间控制的两个处理方式:#wait和#alarm上。如果你不用这两个东西或者很少用。恭喜你!你的Cmud程序会非常稳定,不会出现
烦人的环境异常(比如你开了三个窗口,一个窗口是主游戏窗口,一个窗口记录聊天记录,一个窗口
记录日志,本来所有robot都应该在主游戏窗口运行,但是发现某一个瞬间他把聊天记录那个窗口当作
主游戏窗口运行了,虽然文字还是在主游戏窗口回显,但是robot调用代码都想从聊天记录窗口调用代码,
直接导致你的robot完蛋了),内存错误(很多时候cmud会出现内存冲突错误,或者进程异常错误提示框),
session崩溃(session莫名其妙就不能用了,必须删除当前session,重建新session),cmud系统数据库崩溃
(cmud是用sqlite数据库运行的,有几率会导致整个系统数据库直接崩溃,只能重装cmud)。这些错误
的根源90%都是源于处理不当的时间控制方式上。
    #wait系列指令一共有三种,不过原理相同,以前的文章我也说过,大家自己翻翻论坛吧。经过我这些
个月的细心体会,发现#wait指令不会保护环境,各种莫名其妙的错误90%都是它造成的,而且cmud官方
帮助也说了不要把#wait指令使用在使用非常多全局变量的地方,#wait指令不会保护全局变量,而且常常
由于全局变量导致出现调用异常,以前常常出现指令突然跑到聊天窗口运行或者全局变量跑去聊天窗口去,
或者出现各种各样的内存冲突,进程冲突,数据库冲突,大概都是他造成的。但是#wait指令有一个好处,
他的中断是在主线程中断的,对系统消耗比较少一点,不会自己另建一个新线程。如果你想保持长久运行
关键地方有一些#wait还是很有必要的,否则因为内存消耗过快导致系统频繁重整就麻烦了,cmud的线程
总数是有限制的,创建太多线程必然会导致系统不稳定。
    #alarm指令原理是创建一个新线程运行定时指令,这里就有一个问题,用多了#alarm会导致系统线程数
开销非常大,像上面所说,必然会导致系统不稳定,运行一段时间以后就会发现系统会隔几分钟就会重整
内存,释放线程资源。但是#alarm有一个好处,他是新开线程运行的,所以不像#wait那样会影响主线程的
环境,#wait指令导致的一系列环境灾难他一样都不会犯,所以大多数地方该用还是得用。
    总结,从上面描述可以看出,用多了#wait指令会导致环境灾难,用多了#alarm会导致系统线程资源不足,
有时候就需要两者之间做取舍,还有就是一部分延时可以通过mud客户端到服务器的网络延迟来实现,不需
要用到#wait和#alarm指令,这样子当然是最安全的,不过通过网络延迟来实现,兼容性就不太好了,有的网
络延迟在10ms左右,有的是100ms左右,100ms的用网络延迟来实现就和#wait 100效果相同,但是到了10ms
的网络就变成#wait 10,这个有时候直接就是灾难了,这没办法,大家自己取舍吧。我相信到了Mushclient
上关于线程管理上的稳定性也是很挠头的问题,只是cmud上这个问题更突出而已。我的护镖机器人以前把所有
#wait指令都用#alarm来替换,发现每过了2-4小时,就会导致隔10分钟cmud运行的cpu就会用满100%,前些
日子对那部分进行大手术,把主流的0.5每秒的#alarm作了改动,减少了发生频率,现在基本上运行一天
不会出现100%cpu的问题,所以发了这一篇文章告诉大家。

ddid 发表于 2010-4-18 11:39:32

MUSH呢,如果频繁地重复使用coroutine,确实会溢出,不过还好MUSH有其它的方法,此路不通,换条路走。

CMUD呢,#wait和#alarm都有各自的问题,还有没有更好一点的解决办法?

seagate 发表于 2010-4-18 11:42:04

没办法,我现在更多使用#trigger来控制短时间的时间控制,长时间的时间控制用#alarm问题不大,基本上我的目标是保持运行8小时不出系统异常就可以了!#wait是考虑非常慎重以后才会用用!这个东西杀伤力太大,属于核武器级别的!不能乱用

seagate 发表于 2010-4-18 11:48:39

#timer就一个,怎么都不够用!我现在对于timer就是用来计时和冗灾补救的,不作更多用途。

lkyun 发表于 2010-4-18 12:29:36

可以把timer设置成变量,就相当于有n个timer了

seagate 发表于 2010-4-18 13:10:33

你要并行好几个时间控制根本没办法做啊?你说的不停修改timer的内容肯定不行。
光timer干不了所有时间控制的。有时候要同时有5,6个控制

duno 发表于 2010-4-18 15:57:46

所谓事件驱动,最底下还是timer在做。
无论现实还是程序,保证可靠的唯一方式就是不断尝试直到明确成功或失败。不同的地方在于由谁保证。
比如
timer
  计数器增长
  对比计数器,查看任务列表里有无到时元素
  若有,执行该元素任务内容,并删除该元素
  对周期型任务,不删除元素,而修改到期时间为下次执行时间
任务列表
  每元素两成员 [囧到期时间囧, 囧任务内容囧]

mister 发表于 2010-4-18 16:00:03

我以前一直用cmud,但cmud有两个关键问题,一个是变量甚至alias会穿越sessions,另一个是太容易崩溃了,甚至到整个pkg文件坏掉.现在改回zmud721,爽多了,#alarm其实是十分强大的

seagate 发表于 2010-4-18 16:52:08

cmud的变量和alias穿越session我研究发现90%是由于#wait搞的鬼,当然还有一些命令也会导致穿越,但是那些命令用的比较少,比如切换status windows。
崩溃问题我基本上都解决了,实际上还是由于#wait,只要#wait用的好基本上不会碰到崩溃问题,至少你看我的cmud的3月6日版本的训练机器人,我用了这么长时间,差不多3个月,每周两次full技能,就有一次早上7点崩溃了一次,基本上没有影响,几率已经非常低了。
而且用cmud开发好处是代码复用率高,维护方便,用zmud721就比较麻烦了。

hba 发表于 2010-4-18 18:11:40

原帖由 seagate 于 2010-4-18 01:10 PM 发表 http://www.pkuxkx.com/forum/images/common/back.gif
你要并行好几个时间控制根本没办法做啊?你说的不停修改timer的内容肯定不行。
光timer干不了所有时间控制的。有时候要同时有5,6个控制

这个就体现mush的好了,mush可以并行若干时间控制,在设计机器人的时候是无比方便的,同时大大减少对mud系统的压力。以北侠中mush的范例之一,maper的跳楼机器人为例,只要在timer那里可以很简单的加多一个anti_fadai的函数就达到防发呆的机制,又不影响原来的timer;又比如在设计任务机器人的时候,针对不同目的的系统可以设计不同的timer,如每秒一次的战斗系统,3-5秒的吃药系统,每秒一次的步进系统,等等,各司其职。
而说到代码复用率高,维护方便,mush更是方便吧。我从以前的习惯在zmud上编程,到现在的更沉迷于在notepad++上编程。
至于mush的wait.make,我感觉是很不喜欢。我觉得还是用回内置函数会更安全可靠,doafter,timer和trigger的结合足以完成任何wait的工作了吧。

文若呢?你不是在书剑用mush也卓有成效嘛,在北侠又用的cmud,刚好都有体会的,来谈谈mush和cmud的感觉。

[ 本帖最后由 hba 于 2010-4-18 06:15 PM 编辑 ]
页: [1] 2 3
查看完整版本: Cmud时间控制再揭秘