gettimeofday(取得目前的时间)
有时候需要打印代码执行到某处的时间,或者需要计算程序执行的时间差。这时会用到gettimeofday函数,它可以返回自1970-01-01 00:00:00到现在经历的秒数,
函数说明:
#include <sys/time.h>
int gettimeofday ( struct timeval * tv , struct timezone * tz )
参数都是出参
struct timeval {
time_t tv_sec; //秒
suseconds_t tv_usec; //微秒
};
struct timezone {
int tz_minuteswest; //和Greenwich 时间差了多少分钟
int tz_dsttime; //日光节约时间的状态
};
返回值
成功则返回0,
失败返回-1,错误代码存于errno。
timeval中的tv_sec是time_t类型的,即long的类型。
在32位下为4个字节,能够表示的最大正整数是2147483647,而这个表示的时间最大能到2038-01-19 03:14:07,超过了之后就变为-2147483648,这就是linux2038年的问题。
而64位系统下的time_t类型即long类型长度为8个字节,可以用到几千亿年,这么长的时间完全不用担心溢出的问题。
tz_dsttime 所代表的状态如下
DST_NONE /*不使用*/
DST_USA /*美国*/
DST_AUST /*澳洲*/
DST_WET /*西欧*/
DST_MET /*中欧*/
DST_EET /*东欧*/
DST_CAN /*加拿大*/
DST_GB /*大不列颠*/
DST_RUM /*罗马尼亚*/
DST_TUR /*土耳其*/
DST_AUSTALT /*澳洲(1986年以后)*/
我们很可能会用到精确到毫秒的时间,这样可以这样写,
struct timeval tv;
gettimeofday(&tv, NULL);
int64_t ts = (int64_t)tv.tv_sec*1000 + tv.tv_usec/1000;
注意:
其中的(int64_t)类型转换对于32位的系统是必须的,否则乘上1000会溢出。
clock_gettime(获取不同要求的精确时间)
#include <time.h>
int clock_gettime(clockid_t clk_id, struct timespec* tp);
参数
入参
clk_id : 检索和设置的clk_id指定的时钟时间。
CLOCK_REALTIME:系统实时时间,随系统实时时间改变而改变,即从UTC1970-1-1 0:0:0开始计时,中间时刻如果系统时间被用户改成其他,则对应的时间相应改变
CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响
CLOCK_PROCESS_CPUTIME_ID:本进程到当前代码系统CPU花费的时间
CLOCK_THREAD_CPUTIME_ID:本线程到当前代码系统CPU花费的时间
出参
struct timespec
{
time_t tv_sec; /* 秒*/
long tv_nsec; /* 纳秒*/
};
clock()
这个函数返回从“开启这个程序进程”到“程序中调用C++ clock()函数”时之间的CPU时钟计时单元数(clock tick)
在用多线程练习程序的时候, 需要测试性能,获取程序的运行时间。
一开始使用的是:
clock_t 类,而且这个用法还很简单如下
int i = 100000000;
clock_t start,finish; //定义开始,结束变量
start = clock(); //初始化
while( i-- );
finish = clock(); //初始化结束时间
double duration = (double)(finish - start) / CLOCKS_PER_SEC; //转换浮点型
printf( "%lf seconds\n", duration );
这样就可以了,乍一看很合理呀, 程序开始获取,程序结束了获取时间,
使用注意:
后来查了资料发现clock()函数的功能:
当程序单线程或者单核心机器运行时,这种时间的统计方法是正确的。但是如果要执行的代码多个线程并发执行时就会出问题,因为最终end-begin将会是多个核心总共执行的时钟嘀嗒数,因此造成时间偏大。
time_t
找了半天,linux中time_t的定义,真牛逼。。。。
1、 time.h
```
line77 typedef __time_t time_t;
line116 #include <bits/types.h> /* This defines __time_t for us. */
```
2、bit/types.h
```
l139: __STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
# define __STD_TYPE __extension__ typedef
```
3、#include <bits/typesizes.h>
```
#define __TIME_T_TYPE __SYSCALL_SLONG_TYPE
# define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE
```
4、bit/types.h
```
#define __SLONGWORD_TYPE long int
```
所以time_t是long int型。
上位: https://blog.csdn.net/lyz980926/article/details/43122107
时间纪元
UNIX认为1970年1月1日0点是时间纪元
大多数C语言程序都使用到一个叫做“标准时间库”的程序库,这个时间库用一个标准的4字节也就是32位的形式来储存时间信息。当初设计的时候,这个4字节的时间格式把1970年1月1日凌晨0时0分0秒(这个时间名叫 the Unix Epoch)作为时间起点,这时的时间值为0。以后所有的时间都是从这个时间开始一秒一秒累积得来的。
32位最大时间:
2038年1月19日星期二凌晨03:14:07
至于时间的问题随着64位操作系统的产生逐渐得到解决,因为用64位操作,系统可以时间表示到 292278994-08-17 15:12:55 807
即约2900亿年后的。到那时,位于猎户座旋臂的太阳,已经是黑矮星或暗黑物质,猎户座旋臂已经被重力波震断,银河系大概则已经变成小型似星体了。