Linux下C语言获得系统时间的方法

Linux下C语言获得系统时间的方法,第1张

没有完整程序, 不过能提供一点资料

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

这个函数可以获取当前时间, 貌似只要第一个结构体就行了

struct timeval

{

time_t tv_sec; //秒 [long int]

suseconds_t tv_usec; //微秒 [long int], (10E-6 second)

};

struct timeval

{

long tv_sec;

long tv_usec;

};

然后取微秒的前三位就是小数了, 之后把秒 tv_sec 转化为 tm 格式, 参数用秒的指针就行

struct tm gmtime(const time_t t);

//转换成格林威治时间。有时称为GMT或UTC。

struct tm localtime(const time_t t);

//转换成本地时间。它可以透过修改TZ环境变数来在一台机器中,不同使用者表示不同时间

下面是tm的部分参数

int tm_sec; //tm_sec表「秒」数,在[0,61]之间,多出来的两秒是用来处理跳秒问题用的。/ Seconds: 0-59 (K&R says 0-61) /

int tm_min; //tm_min表「分」数,在[0,59]之间。

int tm_hour; //tm_hour表「时」数,在[0,23]之间。

int tm_mday; //tm_mday表「本月第几日」,在[1,31]之间。

int tm_mon; //tm_mon表「本年第几月」,在[0,11]之间。

int tm_year; //tm_year要加1900表示那一年。 / / 年份,其值从1900开始 //

int tm_wday; //tm_wday表「本周第几日」,在[0,6]之间。 / Days since Sunday (0-6) / /其中0代表星期天,1代表星期一,以此类推 /

int tm_yday; //tm_yday表「本年第几日」,在[0,365]之间,闰年有366日。 /其中0代表1月1日,1代表1月2日,以此类推 //

int tm_isdst; //tm_isdst表是否为「日光节约时间」

------------------------------华丽丽的分割线--------------------------------------------------

由于很长时间没编程了, 也没有Linux环境, 我就简单写几行代码, 仅作参考

#include <stdioh>

#include <timeh>

#include <sys/timeh>

#include<unistdh>

//这四个不一定够用了

struct timeval tv;

struct timezone tz;

struct tm p_tm;

//变量没有初始化习惯不好,不要学

gettimeofday(&tv, &tz);

p_tm = gmtime( (const time_t )&tvtv_sec );

字符串的组装尤其格式问题自己解决吧

年 p_tm->tm_year+ 1900

月 p_tm->tm_mon+ 1

日 p_tm->tm_mday

时 p_tm->tm_hour+ 1

分 p_tm->tm_min+ 1

秒 p_tm->tm_sec+ 1

小数点后面的部分,注意不够三位还是前面填充0 tvtv_sec/1000

clock_gettime

获取的是纳秒级的精度

时间需要保存在 struct timespec 结构体中

gettimeofday

获取的是微妙级精度

时间需要保存在 struct timeval 结构体中

两个函数获取的时间都保存在结构体中,直接相减的?你所问的问题考虑一下时间精度问题。

1纳秒=1000微妙

C语言中提供了许多库函数来实现计时功能

下面介绍一些常用的计时函数

1 time()

头文件:timeh

函数原型:time_t time(time_t timer)

功能:返回以格林尼治时间(GMT)为标准,从1970年1月1日00:00:00到现在的时此刻所经过的秒数

用time()函数结合其他函数(如:localtime、gmtime、asctime、ctime)可以获得当前系统时间或是标准时间。

用difftime函数可以计算两个time_t类型的时间的差值,可以用于计时。用difftime(t2,t1)要比t2-t1更准确,因为C标准中并没有规定time_t的单位一定是秒,而difftime会根据机器进行转换,更可靠。

说明:C标准库中的函数,可移植性最好,性能也很稳定,但精度太低,只能精确到秒,对于一般的事件计时还算够用,而对运算时间的计时就明显不够用了。

2 clock()

头文件:timeh

函数原型:clock_t clock(void);

功能:该函数返回值是硬件滴答数,要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC。比如,在VC++60下,这两个量的值都是1000。

说明:可以精确到毫秒,适合一般场合的使用。

3 timeGetTime()

头文件:Mmsystemh  引用库: Winmmlib

函数原型:DWORD timeGetTime(VOID);

功能:返回系统时间,以毫秒为单位。系统时间是从系统启动到调用函数时所经过的毫秒数。注意,这个值是32位的,会在0到2^32之间循环,约4971天。

说明:该函数的时间精度是五毫秒或更大一些,这取决于机器的性能。可用timeBeginPeriod和timeEndPeriod函数提高timeGetTime函数的精度。如果使用了,连续调用timeGetTime函数,一系列返回值的差异由timeBeginPeriod和timeEndPeriod决定。

4 GetTickCount()

头文件:windowsh

函数原型:DWORD WINAPI GetTickCount(void);

功能:返回自设备启动后的毫秒数(不含系统暂停时间)。

说明:精确到毫秒。对于一般的实时控制,使用GetTickCount()函数就可以满足精度要求。

5 QueryPerformanceCounter()、QueryPerformanceFrequency()

头文件:windowsh

函数原型:BOOLQueryPerformanceCounter(LARGE_INTEGER lpPerformanceCount);

BOOLQueryPerformanceFrequency(LARGE_INTEGER lpFrequency);

功能:前者获得的是CPU从开机以来执行的时钟周期数。后者用于获得你的机器一秒钟执行多少次,就是你的时钟周期。

补充:LARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构, 其具体用法根据编译器是否支持64位而定:

在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率,然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经历的精确时间。

说明:这种方法的定时误差不超过1微秒,精度与CPU等机器配置有关,一般认为精度为透微秒级。在Windows平台下进行高精度计时的时候可以考虑这种方法。

6 gettimeofday()

Linux C函数。

头文件:sys/timeh

函数原型:int gettimeofday(struct timeval tv,struct timezone tz);

说明:其参数tv是保存获取时间结果的结构体,参数tz用于保存时区结果(若不使用则传入NULL即可)。

timeval的定义为:

struct timeval {  

long tv_sec; // 秒数

long tv_usec; //微秒数

}

可见该函数可用于在linux中获得微秒精度的时间。

说明:使用这种方式计时,精度可达微秒。经验证,在arm+linux的环境下此函数仍可使用。

这些函数分别是做不同用处的,有些相互有点关系,有些则完全没有关系,所以没法比较所谓的优缺点。具体每个函数的用法,可以 man xxx 或者在网上搜,我就不复制黏贴了,这里给一个简单的说明:

times: 用来统计进程及其子进程执行所消耗的CPU时间。常见用法是在不同地方调用两次这个函数,从而可以计算出进程或子进程在这两次调用之间消耗了多少CPU时间。

time: 返回当前相对于 Epoch (在linux/unix里,这个时间一般指 1970年1月1日0点0分0秒)所经过的秒数。 常见用法是在不同地方调用两次这个函数,从而可以计算这两处调用之间系统时间过了多少秒。

gettimeofday: 有点类似于time, 获取当前相对于 Epoch 所经过的 秒数+微秒数。

clock: 返回当前进程消耗的CPU时间,用法类似于times, 这个函数返回值是否包含等待子进程的时间在不同的实现中是不一样的,在linux里,不包含。

由上可见, times 和 clock 可以算成一类,用来计算CPU时间

time 和 gettimeofday 可以算成一类,都是用来计算真实时间的

有4种方法可以达成测算程序运行时间的目的。

它们分别是使用clock, times, gettimeofday, getrusage来实现的。

下面就来逐一介绍,并比较它们的优劣点。

系统测试环境:

VirtualBox (Ubuntu 910)

gcc version 441

libc6 2101-0ubuntu16

Core Duo T2500 2GMHz

例程如下:

只要修改第11行的定义值,就可以使用不同的测量方法了。

#include <sys/timeh>

#include <sys/resourceh>

#include <unistdh>

#include <stdioh>

#include <timeh>

#define TEST_BY_CLOCK (char)(0x00)

#define TEST_BY_TIMES (char)(0x01)

#define TEST_BY_GETTIMEOFDAY (char)(0x02)

#define TEST_BY_GETRUSAGE (char)(0x03)

#define TEST_METHOD (TEST_BY_GETTIMEOFDAY)

#define COORDINATION_X (int)(1024)

#define COORDINATION_Y (int)(1024)

static int g_Matrix[COORDINATION_X][COORDINATION_Y];

double getTimeval()

{

struct rusage stRusage;

struct timeval stTimeval;

if (TEST_METHOD == TEST_BY_GETTIMEOFDAY)

{

gettimeofday(&stTimeval, NULL);

}

else if (TEST_METHOD == TEST_BY_GETRUSAGE)

{

getrusage(RUSAGE_SELF, &stRusage);

stTimeval = stRusageru_utime;

}

return stTimevaltv_sec + (double)stTimevaltv_usec1E-6;

}

int main()

{

int i, j;

int n = 0;

clock_t clockT1, clockT2;

double doubleT1, doubleT2;

if (TEST_METHOD == TEST_BY_CLOCK)

{

clockT1 = clock();

}

else if (TEST_METHOD == TEST_BY_TIMES)

{

times(&clockT1);

}

else if (TEST_METHOD == TEST_BY_GETTIMEOFDAY)

{

doubleT1 = getTimeval();

}

else if (TEST_METHOD == TEST_BY_GETRUSAGE)

{

doubleT1 = getTimeval();

}

for (i = 0; i < COORDINATION_X; i++)

{

for (j = 0; j < COORDINATION_Y; j++)

{

g_Matrix[i][j] = i j;

}

}

if (TEST_METHOD == TEST_BY_CLOCK)

{

clockT2 = clock();

printf("Time result tested by clock = %1030f\n",(double)(clockT2 - clockT1)/CLOCKS_PER_SEC);

}

else if (TEST_METHOD == TEST_BY_TIMES)

{

times(&clockT2);

printf("Time result tested by times = %1030f\n", (double)(clockT2 - clockT1)/sysconf(_SC_CLK_TCK));

}

else if (TEST_METHOD == TEST_BY_GETTIMEOFDAY)

{

doubleT2 = getTimeval();

printf("Time result tested by gettimeofday = %1030f\n",(double)(doubleT2 - doubleT1));

}

else if (TEST_METHOD == TEST_BY_GETRUSAGE)

{

doubleT2 = getTimeval();

printf("Time result tested by getrusage = %1070f\n", (double)(doubleT2 - doubleT1));

}

return 0;

}

1 使用clock的方法:

clock是ANSI C的标准库函数,关于这个函数需要说明几点。

首先,它返回的是CPU耗费在本程序上的时间。也就是说,途中sleep的话,由于CPU资源被释放,那段时间将不被计算在内。

其次,得到的返回值其实就是耗费在本程序上的CPU时间片的数量,也就是Clock Tick的值。该值必须除以CLOCKS_PER_SEC这个宏值,才

能最后得到ssmmnn格式的运行时间。在POSIX兼容系统中,CLOCKS_PER_SEC的值为1,000,000的,也就是

1MHz。

最后,使用这个函数能达到的精度大约为10ms。

2 使用times的方法:

times的用法基本和clock类似,同样是取得CPU时间片的数量,所不同的是要除以的时间单位值为sysconf(_SC_CLK_TCK)。

3 使用gettimeofday的方法:

用gettimeofday直接提取硬件时钟进行运算,得到的结果的精度相比前两种方法提高了很多。

但是也正由于它提取硬件时钟的原因,这个方法只能计算程序开始时间和结束时间的差值。而此时系统中如果在运行其他的后台程序,可能会影响到最终结果的值。如果后台繁忙,系统dispatch过多的话,并不能完全真实反映被测量函数的运行时间。

4 使用getrusage的方法:

getrusage得到的是程序对系统资源的占用信息。只要指定了RUSAGE_SELF,就可以得到程序本身运行所占用的系统时间。

实际上,windows和Linux获得时间的机制是不一样的,不是靠代码就能够完成。想在windows下实现gettimeofday,其实就是windows取时间的方式,还有Linux提供了渐进修改时间的接口adjtime(),而windows就没有。

精度达到微妙是不可能的,因为计算机本身的时间片10-15ms左右,不管是Linux和windows,因此不可能达到那个精度。

另外系统时间和RTC时间也是不同的概念,当然读RTC时间成本很高,但是准确,可以用汇编或具体的库来读,但是只是一瞬间的参考,按长远来说也是很不稳定的,做多10-15ms精度,当然,你可以自己用代码时间一个时间估计的过程,用算法来弥补,给出误差分析,但这个是数学了。

获得的值是微秒 microsecond。

比如025139300 ,有效数字是6位,正好符合1秒=1,000毫秒=1,000,000微秒

使用echo microtime(true);直接获得浮点值。

楼主测到一个035时差,可能是巧合正好在350毫秒之间。函数本身精确到微秒的。

以上就是关于Linux下C语言获得系统时间的方法全部的内容,包括:Linux下C语言获得系统时间的方法、为什么有时候用clock_gettime先获取时间比do_gettimeofday后获取时间要大、c语言如何计时等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9544918.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存