https://www.gravatar.com/avatar/f54704641b5fd99f865013a8196d6caf?s=240&d=mp

gowinder个人博客

关于优先队列容器中元素为指针的情况

使用优先队列,元素为指针,如:
typedef priority_queue<TimeEvent*, deque <TimeEvent*>, less<deque<TimeEvent*>::value_type>    TIME_EVENT_QUEUE;
这样比较的话,其结果是比较指针值,如果我要比较TimeEvent中的某个成员,就不行了,经过谷歌,可以采取一个方式,将less替换成一个结构的函数:
struct TimeEventLessComp
{
bool operator () (TimeEvent*& a, TimeEvent*& b) const
{
return a->dwTick > b->dwTick;
};
};
然后申明时改为:
typedef priority_queue<TimeEvent*, deque <TimeEvent*>, TimeEventLessComp>    TIME_EVENT_QUEUE;

关于时间服务的测试结果

经过简单测试,生成500000个计时器,将指针分别插入list和priority_queue,其中priority_queue使用vector容器(不能使用list),先使用list自的sort函数,用时516ms,反复测了几次,都在500ms以上550ms以下 ,对priority_queue进行插入,在500000个的基础上,进行100000次插入,总用时31ms,平均每个0.00031ms
输出结果如下:
list sort time:516 ms
priority_queue push 100000 event use 31 ms time, average 0.000310 ms per event
sorted list sort time:516 ms
sorted list trace 0
sorted list trace 1
….
priority_queue trace 0
priority_queue trace 1
….
经过测试,优先队列明显性能高于LIST的自排序,很适合我的要求!

时间服务实现方式

使用一个单向或者双向链表,或者使用一个优先队列(priority_queue).
队列中的元素为一个计时器对象。计时器对象包括,从标准时间(程序运行时)开始的时间差。越晚触发的计时器,这个值越大,及触发器事件类型。
如果只使用链表,每次插入后,就要进行一次重排,如果使用优先队列,自动插入顺序位置,我想使用优先队列应该效果好些,还要实验。
每次心跳(服务器线程循环),调用时间服务OnTicker函数,此函数检查队列中最前一个计时器的时间值,如果到达或者超过当前时间的时间差,就将此计时器取出,然后调用其触发器事件。
现在,有二个问题还未解答:
1.时间差值的精确程度,精确到什么程度?最好的情况是精确到微秒,那样,时间服务中的队列可能就会到几十万,这样对插入会有多大的影响,需要具体测试。
2.关于时间差的问题,以什么方式设置?目前使用的TICK是DWORD,32位,42亿多毫秒,换成天数是是49.71天,如果时间差直接放系统TICK+触发事件需要的时间,那么很可能会溢出。如果以程序运行时间为0点,且此时间点的系统TICK为SYSTEM_TICK,以此为参照,新加入的事件的时间值EVENT_TICK为:
EVENT_TICK = NOW_TICK(当前系统TICK) - SYSTEM_TICK+NEED_TIME(需要的时间),也就是说存放时有一个换算过程。这样最多可以存放离程序运行49天内的触发器。还没有考虑好

压力测试笔记 2

昨天发现登录时,任务初始化读取数据库操作频繁问题,今天为了找出其它数据库操作频繁问题,加入数据库操作计数变量,如果在登录或者运行某些计算时操作过于频繁,就再输出数据库操作日志,找出原因。

压力测试笔记 1

马上要封测了,现在开始压力测试.
1000个连接上,没有问题,但是登录后问题来了,处理一个登录要1秒钟时间,可想而知1000个需要多长时间.
这是肯定不行.
于是加入测试语句,查找是谁在拖时间.
最后找到是登录时初始化玩家的任务,才发现有900多个任务,每个任务又有小任务,而且小任务不管数据库有没有记录,都要去数据库中SELECT 一次.难怪,明天找人改过来,已经完成和还没有开始的任务就不需要读了.应该会快很多.
又发现写日志问题,在每次TICK调用的函数中,如果有CHECK之类的日志出错,会不停的写,导致服务器没有响应,除了关掉日志写硬盘外,几乎没有别的办法.在介面线程显示时,取日志消息时,每取一个,要加一个判断,看是否超出此次TICK可能使用的时间,如果超出,还未处理的TICK就下次再处理,这样介面就不会死掉了.

windows socket 笔记

10055错误,压力测试客户端开了1000个连接,就报10055错误,查了发现是资源不足,后来想想,应该是连得太快了,服务器响应不过来,所以客户端的缓冲满了.调多点线程,或者发送每个连接的之间停一下.