linux 时间函数

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亿年后的。到那时,位于猎户座旋臂的太阳,已经是黑矮星或暗黑物质,猎户座旋臂已经被重力波震断,银河系大概则已经变成小型似星体了。

猜你喜欢

转载自blog.csdn.net/llffss/article/details/121054508