Linux时间系统及其API

本文函数列表:

获取当前时间(距离1970年)

gettimeofday(2)

获取当前时间(实际字符串)

localtime(3)
asctime(3)
time(2)

setitimer实现定时器

getitimer(2)
setitimer(2)

一、获取当前时间(距离1970年)



struct timeval {
	long tv_sec;	//秒
	long tv_usec;	//微妙
};
struct timezone {
	int tz_minuteswest;	//和Greenwich时间差了多少分钟
	int tz_dsttime; //日光节约时间的状态
};

gettimeofday(2)

#include <sys/time.h>
#include <unistd.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
功能: 取得当前时间
参数:
 tv:回传参数,当前时间
 tz:回传参数,当地时区信息
返回值:
 成功 0
 错误 -1 errno被设置

例:

#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>

gettimeofday(&tv1, &tz);
/*do something*/
gettimeofday(&tv2, &tz);
t = tv2.tv_sec - tv1.tv_sec + (tv2.tv_usec - tv1.tv_usec) * pow(10, -6);	//单位:秒
//pow(10, -6) ------10的-6次方

二、获取当前时间(实际字符串)



localtime(3)
头文件:#include <time.h>
功能: localtime把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转换为本地时间,此函数获得的tm结构体的时间是日历时间。
struct tm *localtime(const time_t *timep);
参数:
 timep:从1970年到现在的时间差,可以使用time(2)函数获取。
返回值:
 返回指向tm 结构体的指针,tm结构体是time.h中定义的用于分别存储时间的各个量(年月日等)的结构体。

asctime(3)
头文件:#include <time.h>
功能: asctime把struct tm结构体保存的时间信息转换为字符串形式
char *asctime(const struct tm *tm);
参数:
 tm:struct tm结构体,表示时间
返回值:
 返回tm结构体指示的时间的字符串格式,字符串中自带’\n’

time(2)
头文件:#include <time.h>
功能: 获得1970年到现在经过了的时间
time_t time(time_t *tloc);
参数:
 tloc:NULL即可;如果非NULL,则返回值也会存在tloc指向的内存中。
返回值:
 获得1970年到现在经过了的时间,保存在struct tm结构体里

注: struct tm结构体

struct tm {
	int tm_sec;    /* Seconds (0-60) */
	int tm_min;    /* Minutes (0-59) */
	int tm_hour;   /* Hours (0-23) */
	int tm_mday;   /* Day of the month (1-31) */
	int tm_mon;    /* Month (0-11) */
	int tm_year;   /* Year - 1900 ,从1900到现在的年数*/
	int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
	int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
	int tm_isdst;  /* Daylight saving time */
};

例:

 1 #include <stdio.h>
 2 #include <stddef.h>
 3 #include <time.h>
 4 int main(void)
 5 {
 6 	time_t timer;//time_t就是long int 类型
 7	struct tm *tblock;
 8	timer = time(NULL);
 9  	tblock = localtime(&timer);
10 	printf("Local time is: %s", asctime(tblock));
11	return 0;
12 }

三、Linux时间和定时器介绍



运行一个进程的时候,进程所消耗的时间包括三个部分:
用户时间:进程消耗在用户态的时间。也叫用户CPU时间;
内核时间:进程消耗在内核态的时间。也叫系统CPU时间;
睡眠时间:进程消耗在等待I/O,睡眠等不被调度的情况下的时间。

墙上时钟时间(wall clock time):等于用户时间+内核时间+睡眠时间
CPU时间:用户时间+内核时间

内核为每个进程维护三个计时器
真实计时器:统计进程的执行时间(墙上时间)
执行时间=用户时间+内核时间+睡眠时间
虚拟计时器:统计进程的用户时间
实用计时器:统计进程的用户时间和内核时间之和

这三个计时器除了统计进程的各种时间外,还可以按照各自的计时规则,以定时器的方式工作,向进程周期性的发送不同信号。
SIGALRM 真实定时器
SIGVTALRM 虚拟定时器
SIGPROF 实用定时器

四、setitimer实现定时器



通过使用setitimer(2)设置、启动、关闭定时器,
使用getitimer(2)
getitimer(2)
#include <sys/time.h>
int getitimer(int which, struct itimerval *curr_value);
功能: 获取当前进程的计时器的当前值
参数:
 which:
  ITIMER_REAL:真实计时器
  ITIMER_VIRTUAL:虚拟计时器
  ITIMER_PROF:实用计时器
 curr_value:回传参数,计时器当前值
返回值:
 成功 0
 错误 -1 errno被设置

setitimer(2)
#include <sys/time.h>
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
功能: 设置定时器,it_value会逐渐递减,当递减到0时会被重新设置为it_interval,然后继续递减,因此it_value是第一次触发定时器的时间,it_interval是后续固定的触发时间间隔。
示例:
 设置it_value为5秒,it_interval为1秒,则定时器开始工作后,5秒后发送一次相应的定时器信号,之后每1秒发送一次相应的信号。
 类似于手机上设置闹钟,设置早晨9点响铃,达到早晨9点后则响铃,第一次响铃后每隔10分钟继续响铃,直到你点击不再响铃。
参数:
 which:
  ITIMER_REAL:真实定时器
  ITIMER_VIRTUAL:虚拟定时器
  ITIMER_PROF:实用定时器
 new_value:定时器新值
 old_value:定时器原来的值
返回值:
 成功 0
 错误 -1 errno被设置

补充:

struct itimerval{
	/*固定的间隔时间*/
	struct timeval it_interval;/*next value*/
	/*第一次定时器触发间隔时间*/
	struct timeval it_value;/*current value*/
};
struct timeval{
	long tv_sec;	/*seconds*/
	long tv_usec;	/**microseconds/
};

:sleep函数实现原理

例:实现类似定时器中断函数

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
void doit(int sig){
	printf("alrm\n");
	return ;
}
int main(void){
	struct itimerval new;
	new.it_value.tv_sec=5;
	new.it_value.tv_usec=0;
	new.it_interval.tv_sec=0;
	new.it_interval.tv_usec=500000;
	signal(SIGALRM,doit);
	setitimer(ITIMER_REAL,&new,NULL);
	while(1);
	return 0;
}

结果:
下方输出结果中第一个alrm是5秒后输出的,剩下的alrm都是间隔0.5输出一次

am@am-PC:test$ ./a.out 
alrm
alrm
alrm
alrm
alrm
alrm
alrm
alrm
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值