Chinaunix首页 | 论坛 | 博客
  • 博客访问: 544171
  • 博文数量: 493
  • 博客积分: 2891
  • 博客等级: 少校
  • 技术积分: 4960
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 17:11
文章分类

全部博文(493)

文章存档

2010年(493)

分类:

2010-05-12 19:54:00

1 现象:问题描述
AIX操作系统,产品A开始运行后,停了一段时间才开始进行呼叫,但系统不接收任何呼叫。经过一段时间后,系统恢愎正常,可以接入呼叫。这段时间不定有多长,可能几十秒,也可能半个多小时。
2 关键过程:根本原因分析
由于GetTickCount函数是在头文件中使用inline函数实现,其中使用了静态变量。inline函数中的变量应该是在第一次调用时被初始化,但AIX VAC 6.0编译器处理此情况时存在Bug:只要是某个cpp文件中第一次调用,都将inline函数中的静态变量初始化一遍。结果导致呼叫进来后,GetTickCount函数中记录时间的变量被重新初始化,这样所有的事件超时时间都被延长。此延长的时间取决于第一次执行GetTickCount函数的时间与呼叫进入后执行GetTickCount函数的时间差。
以下是GetTickCount函数的实现:
gettickcount.h
/*******************************************************************************
Desc      : 将timeval封装成类,在变量被定义时自动调用构造函数取得系统时间
*******************************************************************************/
class CTime_INFOX
{
    friend DWORD ICD_GetTickCount();
    public:
        CTime_INFOX()
        {
   struct timespec tp;
   clock_gettime(CLOCK_REALTIME,&tp);
            tv_sec = tp.tv_sec;
            tv_nsec = tp.tv_nsec;
        }
    private:
        unsigned long tv_sec;
        long  tv_nsec;
};
inline DWORD ICD_GetTickCount()
{
    static CTime_INFOX  starttime;   // 静态变量,程序启动时调用构造函数,保存程序启动时间
   
    // 计算当前时间与系统启动时间的差
 struct timespec tp;
 clock_gettime(CLOCK_REALTIME,&tp);
    //时间回调到启动之前将导致时间定时器无法触发问题修改
    if (tp.tv_sec < starttime.tv_sec)
    {
        starttime.tv_sec = tp.tv_sec;
        starttime.tv_nsec = tp.tv_nsec;
    }
   
    return ((tp.tv_sec - starttime.tv_sec)*1000 + (tp.tv_nsec - starttime.tv_nsec)/1000000);   
};
3 结论:解决方案及效果
将GetTickCount函数实现放在cpp文件中,不在头文件中使用inline函数来实现。问题解决。
4 经验总结:预防措施和规范建议
AIX VAC 6.0编译器不能在inline函数中使用static变量,否则会导致不可预期的程序行为。AIX VAC 7.0编译器已解决了此问题。HP下的编译器未发现类似现象。
5 备注
NA
6 考核点
AIX VAC 6.0编译器存在的bug
7 试题
以下哪个编译器在inline函数中使用static变量,static变量可能会被初始化多次?(B)
A. HP ANSI C++ B3910B A.03.55
B. AIX VAC 6.0
C. AIX VAC 7.0
D. 以上所有编译器
阅读(729) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~