事件的危机——调试手记之一[2]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 leeky 的 blog

解决办法:给commdata加上havedata成员,然后在判断中以此为条件,
 调整语句currfunc:=funcwait;的位置,即当下位机尚未转换功能时,没有数据,则上位机不设置当前功能为等待。
        else if (commdata.data[2]=$1d)  
        then begin
           if commdata.havedata  // 新增条件,在解算数据中设置
            then begin
               if (currfunc=funcreadroad)
               then processa       // 写入道路数据库
               else processb;      // 写入巡查数据库
               currfunc:=funcwait; // 调整这行的位置
            end;
        end;

修改后,发现新的问题
问题b.程序不响应用户
    发现程序不响应,强行终止,发现数据库中写入很多的记录。
分析:程序在执行某个循环不能跳出,但查看程序并无循环。
  跟踪,发现程序不断进重复processa或processb的操作。很令人惊奇。思索良久,程序的前提是(commdata.data[2]=$1d),而数据发送结束的空闲状态就是不断地发送此语句;但查看源代码,在processa及processb之后把功能设为了等待状态的,照理不会进入数据处理过程,但此数据处理过程确实不断地出现,因而程序一定未进入等待状态,程序一定是在设置currfunc:=funcwait之前又进入了数据处理过程,那么事情就豁然开朗了:在数据发送结束后,收到第一个结束信号,便进入数据处理过程,并准备设置状态为等待,在数据处理尚未完成时,又收到一条结束命令(空闲时每秒一次,不得不再次诅咒糟糕的协议!),程序继续进入数据处理过程,由此,总在未处理完毕都再次进入处理过程。串口事件导致不断地重复处理(空闲状态下位机每隔一秒发送一次,我测试我的处理过程需要三四秒才能完成)。
解决办法:明白怎么回事,解决就简单了,先设置当前状态,再处理数据,相应程序改为:
       else if (commdata.data[2]=$1d)  
        then begin
        if commdata.havedata
            then begin
               if (currfunc=funcreadroad)
               then begin
                 currfunc:=funcwait;  //  先设置等待状态。
                 processa             //  写入道路数据库
               end
               else begin
                 currfunc:=funcwait;  //  先设置等待状态。
                 processb;            //  写入巡查数据库
               end; 
            end;
        end;
经验:事件的不断发生使程序进入了循环!
如果只是界面的显示,也可以用防止重入的方法解决:
if inmyprocess then exit;
inmyprocess:=true;
   myprocess;          // 处理过程。
inmyprocess:=false;    // 最后设置为假,可以再次进入。

这与临界值的使用原理应当是一样的,请参考 tcriticalsection,记得使用syncobjs 单元。

后记--感悟:
1、程序有问题时,首先去检查你自己的代码,而不要怀疑操作系统或其它,只有在较充分地排除自己程序中的错误后才去怀疑其它,因为操作系统的问题一般来说远少于程序的错误;
2、在设计程序时,要有清晰的思路,不相干的代码要分离,这样有利于逐步求精;
3、认真的态度,不要想当然。当养成了这种习惯后,你不但能很快找出他人程序的毛病,也同样能快速找到自己程序中的bug根源;
4、怀疑一切,你才能获得真知。但要注意不要“打倒一切”,一定要相信已经存在的事实;
5、最好能在事先能预想到可能出错的地方,要做容错处理;对于不能用代码防止的用户操作(比如删除文件)心里应有底,这样当用户的一些操作引起系统不正常时,即使不看源程序也能给予有效的技术支持。

本文关键:调试 串口 事件
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top