Linux时间管理和定时学习笔记

时间的概念

计算机中处处需要时间

  • 程序运行时间(音视频播放进度、下载、上传)
  • 系统日志log
  • QQ、微信、短信聊天记录
  • 当前时间、上班时间、睡觉时间
  • 周期性做一些事情(杀毒、清理垃圾、软件升级更新)
  • 定时开关机
  • OS调度:时间片、定时器

时间分类

  • 绝对时间:2020年1月5日、开机时间
  • 相对时间:万历15年、明天、下周、明年、昨天

时区的概念

  • 标准时间:
    • UTC:Coordinated Universal Time,世界协调时间
    • GMT:Greenwich Mean Time,格林威治标准时间、子午线
  • 本地时间:
    • 北京时间:东8区、UTC/GMT+08:00
    • 计时误差:手表时间快了?慢了?

时间的计量

计时器的发展历程

  • 日出日落、月圆月缺、春夏交替
  • 日晷、沙漏、刻漏
  • 机械钟
  • 石英振荡器、晶振
  • 铯原子钟
  • 氢原子钟、铷原子钟

计算机中的计时

  • 51单片机:晶振
  • 嵌入式系统:定时器
  • PC计算机:定时器
  • 实时时钟:独立电源(CMOS电池、手机晶振)

时间之源

  • 原子时钟
  • 铯原子钟、铷原子钟
  • 各地实验室原子钟
  • 中国科学院国家授时中心
  • 系统时间校准

Linux系统中的时间管理

Linux内核对时间的维护

  • 定时器—时钟中断–时钟节拍tick—jiffies
  • 实时时钟–xtime
  • jiffies:内核中的全局变量,系统启动以来的节拍数
  • HZ:中断频率
  • xtime:内核中的全局变量,墙上时间、UTC

在这里插入图片描述

获取当前时间

全局变量:xtime

  • typedef long time_t;
  • time_t time(time_t *tloc);
  • int stime(const time_t *t);
    在这里插入图片描述

时间格式转换

把秒数转换为年月日时分秒

  • struct tm *gmtime (const time_t *timep);
  • struct tm *localtime (const time_t *timep);
  • time_t mktime(struct tm *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 */ 
	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 */ 
};

在这里插入图片描述

将时间转换为字符串

时间格式->字符串格式

  • char *asctime(const struct tm *tm);
  • char *ctime(const time_t *timep);
    在这里插入图片描述

指定格式的字符串

用户自定义格式

  • size_t strftime (char *s, size_t max, const char *format, const struct tm *tm);
  • char *strptime (const char *s, const char *format, struct tm *tm);

在这里插入图片描述
字符串格式

%a :星期几名称的简写
%A :星期几名称的全称
%b :月份名称的简写
%B :月份名称的全称
%c :首选的日期和时间表示法
%C :世纪(年份除以 1000099%d :一个月中的第几天(0131%D :时间格式,与 %m/%d/%y 表示法相同
% :一个月中的第几天(131%g : 与 %G 表示法类似,但不带世纪
%h :与 %b 表示法相同
%H - 小时,使用 24 小时制(0023%I :小时,使用 12 小时制(0112%j :一年中的第几天(001366%m :月份(0112%M :分
%n :换行符
%p :与给定的时间值相对应的 am 或 pm
%r : a.m. 和 p.m. 的时间标记法
%R : 24 小时制的时间标记法
%S : 秒
%t : tab 制表符
%T :当前时间,与 %H:%M:%S 表示法相同
%u :星期几的数字表示(17%U :当年周数
%w :十进制数形式表示一周中的某天,Sunday[星期日] = 0
%x :首选的日期表示法,不带时间
%X :首选的时间表示法,不带日期%y
%Y :包含表示世纪的数字的年份表示
%Z :时区名称
%z :时区名称的简写
%% :输出一个 % 字符

获取高精度时间

微秒

微秒级时间

  • int gettimeofday (struct timeval *tv, struct timezone *tz);
  • int settimeofday (const struct timeval *tv, const struct timezone *tz);
struct timeval {
	 time_t tv_sec; /* seconds */ 
 	suseconds_t tv_usec; /* microseconds */ 
};
struct timezone { 
	int tz_minuteswest; /* minutes west of Greenwich */ 
	int tz_dsttime; /* type of DST correction */ 
};

在这里插入图片描述

纳秒

纳秒级时间

  • int clock_gettime (clockid_t clk_id, struct timespec *tp);
  • int clock_settime (clockid_t clk_id, const struct timespec *tp);
struct timespec
{
	time_t tv_sec; /* seconds */
	long tv_nsec; /* nanoseconds */
};

在这里插入图片描述
纳秒级时间
– 参数:clock_id

  • 说明:设置时钟时间类型
  • CLOCK_REALTIME:系统实时时间(从1970-1-1 计时)
  • CLOCK_MONOTONIC:系统启动时间
  • CLOCK_PROCESS_CPUTIME_ID:当前进程CPU花费时间
  • CLOCK_THREAD_CPUTIME_ID:当前线程CPU花费时间

Linux中的定时器

内核对定时器的维护

  • 定时器中断—OS维护全局变量—系统调用API—获取/设置时间
  • 定时器中断— 周期动作:发信号、新建线程
  • 周期性工作:
    • 定时杀毒
    • 数据备份
    • 邮件提醒
    • 日志清理

在这里插入图片描述

相关API

  • 内核API:add_timer、mod_timer、del_timer
  • 简单的闹钟:alarm、sleep、usleep、nanosleep
  • 计时器(interval timer):getitimer、setitimer
  • 高级定时器(POSIX timer)
    • timer_create
    • timer_settime
    • timer_gettimer
    • timer_delete
    • timer_getoverrun

interval timer

定时器+signal

  • interval timer,共享相同的定时器
    • 定时器到期,发送信号到当前进程【定时器精度:微秒级】
    • int getitimer (int which, struct itimerval *curr_value);
    • int setitimer (int which, const struct itimerval *new_value, struct itimerval *old_value);
struct itimerval { 
	struct timeval it_interval; /* Interval for periodic timer */ 
	struct timeval it_value; /* Time until next expiration */ 
}; 
struct timeval { 
	time_t tv_sec; /* seconds */ 
	suseconds_t tv_usec; /* microseconds */ 
};

函数参数

  • which:定时器类型
  • ITIMER_REAL:实时计时,到期后发送SIGALRM信号到进程
  • ITIMER_VIRTUAL:进程用户态运行才计时,到期发送SIGVTALRM信号
  • ITIMER_PROF:进程在用户和内核空间都计时,到期发送SIGPROF信号

POSIX timer

POSIX定时器API

  • 编译链接:-lrt
  • int timer_create (clockid_t clockid, struct sigevent *sevp, timer_t *timerid);
  • int timer_gettime (timer_t timerid, struct itimerspec *curr_value);
  • int timer_settime (timer_t timerid, int flags, const struct itimerspec *new_value,struct itimerspec *old_value);
  • int timer_getoverrun (timer_t timerid);
  • int timer_delete (timer_t timerid);

函数参数: sevp

typedef struct sigevent {
	 __sigval_t sigev_value; // timer的ID 
	 int sigev_signo; // 发送信号类型 
	 int sigev_notify; // 定时器到期之后的动作:发信号、线程 
	 void (*sigev_notify_function) (__sigval_t); /* Function to start. */ 
	 void *sigev_notify_attributes; /* Really pthread_attr_t.*/ 
} sigevent_t;
union sigval {
	int sival_int; // args
	void *sival_ptr; //timer ID
};
struct itimerspec { 
	struct timespec it_interval; 
	struct timespec it_value; 
};

函数参数:clockid

  • CLOCK_REALTIME:系统实时时间
  • CLOCK_MONOTONIC:系统启动以来的绝对时间
  • CLOCK_PROCESS_CPUTIME_ID:进程运行时间(用户和内核空间)
  • CLOCK_THREAD_CPUTIME_ID:线程运行时间(用户和内核空间)

sevp.sigev_notify:定时器到期后的动作

  • SIGEV_NONE:什么都不做
  • SIGEV_SIGNAL:发送信号给当前进程
  • SIGEV_THREAD:开启一个线程,执行用户指定function
  • SIGEV_THREAD_ID:给当前进程中的指定线程发信号
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值