在内核中有3个不同的时间:
Wall time(real time), Process time和Monotonic time.
Wall time,也就是rtc时钟。
Process time,进程执行的时间。
Monotonic time,也就是系统从boot后到当前的时间。
表示时间的数据结构:
typedef __timer_t timer_t;
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
struct timespec
{
__time_t tv_sec; /* Seconds. */
long int tv_nsec; /* Nanoseconds. */
};
其中第三个最好,因为他能精确到纳秒。
上面的所能表示的是秒,我们有时需要更直观的表示,因此就有下面的数据结构;
struct tm
{
int tm_sec; /* Seconds. [0-60] (1 leap second) */
int tm_min; /* Minutes. [0-59] */
int tm_hour; /* Hours. [0-23] */
int tm_mday; /* Day. [1-31] */
int tm_mon; /* Month. [0-11] */
int tm_year; /* Year - 1900. */
int tm_wday; /* Day of week. [0-6] */
int tm_yday; /* Days in year.[0-365] */
int tm_isdst; /* DST. [-1/0/1]*/
#ifdef __USE_BSD
long int tm_gmtoff; /* Seconds east of UTC. */
__const char *tm_zone; /* Timezone abbreviation. */
#else
long int __tm_gmtoff; /* Seconds east of UTC. */
__const char *__tm_zone; /* Timezone abbreviation. */
#endif
};
clock_getres这个函数得到不同时钟的精度,也就是时钟间隔:
int clock_getres(clockid_t clk_id, struct timespec *res);
#include <stdio.h>
#include <time.h>
int main()
{
clockid_t clocks[]= {
CLOCK_REALTIME,
CLOCK_MONOTONIC,
CLOCK_PROCESS_CPUTIME_ID,
CLOCK_THREAD_CPUTIME_ID,
(clockid_t) -1,
};
int i;
for(i=0;clocks[i] != (clockid_t) -1;i++)
{
struct timespec res;
int ret;
ret = clock_getres(clocks[i],&res);
if(ret)
perror("clock_getres");
else
printf("clock = [%d],sec = [%ld],nsec = [%ld]\n",clocks[i],res.tv_sec,res.tv_nsec);
}
return 1;
}
我的amd的cpu下,输出结果是这样的:
clock = [0],sec = [0],nsec = [4000250]
clock = [1],sec = [0],nsec = [4000250]
clock = [2],sec = [0],nsec = [1]
clock = [3],sec = [0],nsec = [1]
其中4000250刚好是0.04秒,也就是说x86的架构的系统时钟频率为250hz。。
得到当前的时间的函数:
extern time_t time (time_t *__timer) __THROW;
int gettimeofday(struct timeval *tv, struct timezone *tz);
int clock_gettime(clockid_t clk_id, struct timespec *tp);
#include <stdio.h>
#include <time.h>
int main()
{
clockid_t clocks[]= {
CLOCK_REALTIME,
CLOCK_MONOTONIC,
CLOCK_PROCESS_CPUTIME_ID,
CLOCK_THREAD_CPUTIME_ID,
(clockid_t) -1,
};
int i;
for(i=0;clocks[i] != (clockid_t) -1;i++)
{
struct timespec res;
int ret;
ret = clock_gettime(clocks[i],&res);
if(ret)
perror("clock_getres");
else
printf("clock = [%d],sec = [%ld],nsec = [%ld]\n",clocks[i],res.tv_sec,res.tv_nsec);
}
return 1;
}
通过结果可以看出4个时钟的不同含义。比如CLOCK_REALTIME我们可以看到结果就是从1970年以来所经过的秒数。。
设置时间的函数和get差不多:
int stime(time_t *t);
int settimeofday(const struct timeval *tv, const struct timezone *tz);
int clock_settime(clockid_t clk_id, const struct timespec *tp);
这里要注意,在大部分系统我们设置时钟,只能设置CLOCK_REALTIME。。
这里还有一个更高级的函数:
#include <sys/timex.h>
int adjtimex(struct timex *buf);
这个函数用来同步内核的时钟。具体的用法可以去看man。。
sleep的4个函数:
sleep
usleep
int nanosleep(const struct timespec *req, struct timespec *rem);
long sys_clock_nanosleep (clockid_t which_clock, int flags, const struct timespec *rqtp, struct timespec *rmtp);
sleep和usleep区别不大,一个是秒,一个是毫秒而已。
nanosleep和他们的区别是它使用纳秒,并且他不是用信号来实现的,因此建议使用nanosleep,而不要使用sleep和usleep。
而最后一个函数我们可以选择所取的时钟。。