我是靠谱客的博主 震动老师,最近开发中收集的这篇文章主要介绍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 worldn");

    gettimeofday(&t_end,NULL);

    printf("cost time %ldusn", t_end.tv_usec - t_start.tv_usec);

}

运行结果:

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

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 worldn");

    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 %fsn", 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 worldn");

    gettimeofday(&t_end,NULL);

    printf("cost time %lfsn", RunTimeCnt(&t_start, &t_end));

}

最后

以上就是震动老师为你收集整理的struct timeval用法与时间溢出问题的全部内容,希望文章能够帮你解决struct timeval用法与时间溢出问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部