struct timeval用法与时间溢出问题

1.用法

高精度计算时间的结构体struct timeval。
头文件是sys/time.h

网上查找的定义是


#include "sys/time.h"
 
struct timeval  
{  
__time_t tv_sec;        /* Seconds. */  
__suseconds_t tv_usec;  /* Microseconds. */  
};

tv_sec成员为秒,tv_usec为微秒。1秒=1000000微秒。
__time_t和__suseconds_t都为long int类型。

不知道为何我Ubuntu系统没有/usr/include/sys这个目录。
查找发现time.h的系统头文件有如下几个

./usr/include/linux/time.h
./usr/include/time.h
./usr/include/x86_64-linux-gnu/sys/time.h
./usr/include/x86_64-linux-gnu/bits/time.h
./usr/include/libavutil/time.h
vi /usr/include/linux/time.h

#ifndef _LINUX_TIME_H
#define _LINUX_TIME_H

#include <linux/types.h>


#ifndef _STRUCT_TIMESPEC
#define _STRUCT_TIMESPEC
struct timespec {
    __kernel_time_t tv_sec;         /* seconds */
    long        tv_nsec;        /* nanoseconds */
};
#endif

struct timeval {
    __kernel_time_t     tv_sec;     /* seconds */
    __kernel_suseconds_t    tv_usec;    /* microseconds */
};

使用方法:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

void main(void)
{
    struct timeval t_start, t_end;

    gettimeofday(&t_start,NULL);

    printf("hello world\n");

    gettimeofday(&t_end,NULL);

    printf("cost time %ldus\n", t_end.tv_usec - t_start.tv_usec);

}

运行结果:

hello world
cost time 70us
gettimeofday(&t_start,NULL);
sleep(1);
printf("hello world\n");

hello world打印函数前增加sleep,延时一秒。按照我期望的结果应该1000070us这个样子。但实际运行结果为:

hello world
cost time 381us

注意事项:
当初自己以为这两个成员是独立分开的,只是计算单位不一样。其实这两个成员函数要结合起来使用,一个负责统计秒另外一个负责统计微秒,纠正一下自己的错误认识。

修改后的代码:

void main(void)
{
    struct timeval t_start, t_end;
    float time_consumed;

    gettimeofday(&t_start,NULL);
    sleep(1);
    printf("hello world\n");

    gettimeofday(&t_end,NULL);

    time_consumed = (t_end.tv_sec - t_start.tv_sec) + (t_end.tv_usec - t_start.tv_usec) * 0.000001;

    printf("cost time %fs\n", time_consumed);

}

运行结果:

hello world
cost time 1.000357s

注意事项:

time_consumed = (t_end.tv_sec - t_start.tv_sec) + (t_end.tv_usec - t_start.tv_usec) / 1000000;

使用这种方式运行结果,小数点后面一直都为0.

hello world
cost time 1.000000s

根本原因是c语言中对于除法运算符,当被除数和除数都是整数时,并不会得到一个浮点型的数,而是直接舍去小数部分(即向下取整)。这个细节没注意,太坑了。

2.溢出现象

测试接口调用过程中就会出现溢出问题。

[runtime] The call to the client-side GetInfo interface ends and cost time 0.53772s
[runtime] The client RPC requests and accepts the server response total cost time 0.55354s

[runtime] The call to the client-side GetInfo interface ends and cost time 1.-971693s
[runtime] The client RPC requests and accepts the server response total cost time 1.-970106s

根本原因是定义的数据类型长度不够。针对极端时间超过tv_nsec的长度引起溢出。

当初觉得float单精度已经够用,果然还不太行,需要double类型来进行存储。

重新封装一个统计时间的接口。

/************************************************************************
**函数:RunTimeCnt
**功能:计算接口起止运行时间
**参数:[in] t_start:开始时间,t_end:结束时间 (由gettimeofday获取)
**返回:运行时间,单位秒。
************************************************************************/
double RunTimeCnt(struct timeval *t_start, struct timeval *t_end)
{
  long int time_consumed_sec = 0;//单位秒
  long int time_consumed_usec = 0;//单位微秒
  double time_consumed;//单位秒

  time_consumed_sec = (t_end->tv_sec - t_start->tv_sec);
  time_consumed_usec = t_end->tv_usec - t_start->tv_usec;
  time_consumed = (double)(time_consumed_sec + (time_consumed_usec * 0.000001));

  return time_consumed;
}
void main(void)
{
    struct timeval t_start, t_end;
    float time_consumed;

    gettimeofday(&t_start,NULL);
    sleep(1);
    printf("hello world\n");

    gettimeofday(&t_end,NULL);

    printf("cost time %lfs\n", RunTimeCnt(&t_start, &t_end));

}
  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值