状态迁移时“事件队列”还有事件没处理,怎么处理,避免
本来是状态A的事件,但是状态已经转移到了状态B, 那事件队列里的事件该怎么处理,全丢了,感觉不好,大神分析下这个问题 人已结婚,还能脚踏两只船么 如果某个状态机获得CPU资源的频率是10HZ,事件触发的频率是100HZ,这样每次状态机获得CPU使用权时需要处理10次事件,而我的状态机理念是这样的,把该状态机获得CPU资源的频率提升到200HZ,每次处理一个事件,不需要队列。
macaroni 发表于 2015-5-4 14:05
如果某个状态机获得CPU资源的频率是10HZ,事件触发的频率是100HZ,这样每次状态机获得CPU使用权时需要处理1 ...
事件可能并发的,没有队列,可能会丢事件吧?
状态A离开前发送A_END事件到信息队列,然后进入等A_END状态,收到A_END就可以放心进入状态B了 要看这个事件的重要程度,如果真的非常重要,而且又确实存在你说的这种情况,请另开一个专门的事件队列。
如果事件不那么重要,基本上可以做丢弃处理。 要看这个事件的重要程度,如果真的非常重要,而且又确实存在你说的这种情况,请另开一个专门的事件队列。
如果事件不那么重要,基本上可以做丢弃处理。 只是感觉不好?
要么加快处理速度,要么放心的丢弃 Gorgon_Meducer 发表于 2015-5-5 10:25
要看这个事件的重要程度,如果真的非常重要,而且又确实存在你说的这种情况,请另开一个专门的事件队列。
...
好的,谢谢,我是参考QP-NANO的时候 想到这个问题的,是不是它也存在这样的问题,
以下是QP_NANO的 状态转换代码
void QFsm_dispatch_(QFsm *const me) {
if ((*me->state.fun)(me) == (QState)Q_RET_TRAN) { /* tran. taken? */
Q_SIG(me) = (QSignal)Q_EXIT_SIG;
(void)(*me->state.fun)(me); /* exit the source */
Q_SIG(me) = (QSignal)Q_ENTRY_SIG;
(void)(*me->temp.fun)(me); /* enter the target */
me->state.fun = me->temp.fun; /* record the new active state */
}
}
也没有对事情队列做处理,很可能会把上个状态的没有处理的直接带到下个状态,
由于个人水平的问题,所以很困惑
以下是我改了的代码,直接清队列
static void Fsm_dispatch(Active_t *me,Event_t const *e)
{
StateHandler_t s = me->fsm.state;
State_t r = (*s)(me,e);
if(r == RET_TRAN){
(void)(*s)(me,&ReservedEvt);
/*???if state transmit clear event pool*/
/*atom start*/
if(me->numUsed>0){
__disable_interrupt( );
me->head = 0; /*index to the event queue head*/
me->tail = 0; /*index to the event queue tail*/
me->numUsed= 0; /*number of events currently in queue*/
me->tickCtr= 0; /*time down counter*/
__enable_interrupt( );
}
/*atom end*/
(void)(*me->fsm.state)(me,&ReservedEvt);
}
} LinuxTux.China 发表于 2015-5-5 10:57
只是感觉不好?
要么加快处理速度,要么放心的丢弃
加速的话,理论上还是会碰到这样的情况的,我现在暂时选择丢掉,编程的时候注意这个问题 逻辑上既然状态已经转移,当然不用处理其它状态的事件。如果逻辑上确实要处理这个事件,既然用的QP,可以使用层次状态机。事件的平均处理速度必须大于等于事件的平均产生速度(“平均”是因为有事件队列缓冲),否则这个设计就是失败的,因为要完成一个不可能的事情,这时要升级速度更快的处理器。
页:
[1]