gettimeofday引起的bug

1. BUG描述

使用网关来管理若干个子设备,子设备每隔15秒来给网关发送心跳包。当网关超过45秒没有收到子设备的心跳包时,则认为子设备异常,需要重启子设备。

观察日志,发现子设备频繁重启,不符合设计要求.

2. BUG分析

观察系统的日志,发现系统上电时比较容易出现重启子设备的现象。因为系统是使用ntp来同步时间的,遂怀疑是时间不对引起的。

ntp服务采用的是ntpdate作为客户端。每分钟由cron同步一次。为了降低bug复现的难度,将同步间隔改为5分钟一次,观察bug是否必现。

抓取日志如下图

由上图可知,在NTP同步的前后,确实发生了子设备重启的问题。

再结合代码分析,终于发现了问题,原来代码中使用了gettimeofday!

gettimeofday是获取本地时间的,其值会随着系统时间的改变而改变。应该采用clock_gettime!

3. gettimeofday介绍

gettimeofday原型如下:

#include <time.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);

说明: tz可以为NULL

struct timeval {

    time_t      tv_sec;     /* seconds */

    suseconds_t tv_usec;    /* microseconds */

};

gettimeofday的功能是将自1970-01-01 00:00:00 +0000 (UTC)以来的秒数和微秒数放入tv 中,当返回值为0时表示成功,否则失败。

注意:获取到的时间会随着系统时间的改变而改变。

4. clock_gettime介绍

#include <time.h>

int clock_gettime( clockid_t clock_id,struct timespec * tp );

说明:

     clock_id: 表示获取时间的类型

struct timespec {

    time_t tv_sec;     // 秒

    long   tv_nsec;    // 纳秒

};

clock_gettime的功能是返回某种类型的时间--包括秒和纳秒,其类型与参数clock_id有关。

当返回值为0时表示成功,否则失败。

clock_id的取值以及意义:

CLOCK_REALTIME: 是指系统时间,随着系统时间的改变而改变。系统时钟会被用户而改变。

CLOCK_MONOTONIC: 指从系统启动时开始计时。不受系统影响,也不会被用户改变。

CLOCK_PROCESS_CPUTIME_ID: 指这个进程运行到当前代码时,系统花费的时间。

CLOCK_THREAD_CPUTIME_ID: 指这个线程运行到当前代码时,系统花费的时间。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值