Linux下的时间

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/feilengcui008/article/details/51427031 时钟...
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/feilengcui008/article/details/51427031

时钟

  • 硬件时钟

    • RTC(real time clock),记录wall clock time,硬件对应到/dev/rtc设备文件,读取设备文件可得到硬件时间
    • 读取方式
      • 通过ioctl

        #include <linux/rtc.h>
        int ioctl(fd, RTC_request, param);
      • hwclock命令
    • 通常内核在boot以及从低电量中恢复时,会读取RTC更新system time
  • 软件时钟

    • HZ and jiffies, 由内核维护,对于PC通常HZ配置为 1s / 10ms = 100
    • 精度影响select等依赖timeout的系统调用
    • HRT(high-resolution timers). Linux 2.6.21开始,内核支持高精度定时器,不受内核jiffy限制,可以达到硬件时钟的精度。
  • 外部时钟

    • 从网络ntp,原子钟等同步

时间

  • 时间类别

    • wall clock time => 硬件时间
    • real time => 从某个时间点(比如Epoch)开始的系统时间
    • sys and user time => 通常指程序在内核态和用户态花的时间
  • 时间的表示

    • time_t 从Epoch开始的秒数
    • calendar time 字符串
    • 拆分时间 struct tm

      struct tm {
      int tm_sec; /* seconds */
      int tm_min; /* minutes */
      int tm_hour; /* hours */
      int tm_mday; /* day of the month */
      int tm_mon; /* month */
      int tm_year; /* year */
      int tm_wday; /* day of the week */
      int tm_yday; /* day in the year */
      int tm_isdst; /* daylight saving time */
      };
    • struct timeval/struct timespec
      struct timeval {
        time_t seconds;
        suseconds_t useconds;
      }
      
      struct timespec {
        time_t   tv_sec;        /* seconds */
        long     tv_nsec;       /* nanoseconds */
      };

系统时间的操作

#include <time.h>
#include <sys/time.h>

// number of seconds since epoch
time_t time(time_t *t) 

//参数time_t*
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);

struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);

struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

//参数struct tm*
char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
time_t mktime(struct tm *tm);


int gettimeofday(struct timeval *tv, struct timezone *tz);//如果系统时间调整了会影响
int clock_gettime(clockid_t clk_id, struct timespec *tp);

//将tm按照format处理后放到s
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);

//将字符串时间s按照format格式化后放入tm
char *strptime(const char *s, const char *format, struct tm *tm);

定时器

  • sleep
unsigned int sleep(unsigned int seconds);
  • usleep
int usleep(useconds_t usec);
  • nanosleep
int nanosleep(const struct timespec *req, struct timespec *rem);
  • alarm
// SIGALARM after seconds
unsigned int alarm(unsigned int seconds);
  • timer_create
int timer_create(clockid_t clockid, struct sigevent *sevp,
                        timer_t *timerid);
  • setitimer
  • timerfd_create + select/poll/epoll
int timerfd_create(int clockid, int flags);
  • select
// struct timeval可以精确到微秒(如果硬件有高精度时钟支持)
int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
// struct timespec可以精确到纳秒,但是pselect下次无法修改timeout 
int pselect(int nfds, fd_set *readfds, fd_set *writefds,
                   fd_set *exceptfds, const struct timespec *timeout,
                   const sigset_t *sigmask);

// 一般能提供周期,延时,时间点触发,但核心还是时间点触发的timer
// 1.call_period => 触发一次重新注册call_at
// 2.call_later => 转换为call_at 
// 3.call_at => 时间点触发的timer可以用一个优先级队列保存
  • poll
// timeout最小单位ms,并且rounded up to系统时钟的精度
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
// 注意timespec会被转换成ms
int ppoll(struct pollfd *fds, nfds_t nfds,
               const struct timespec *timeout_ts, const sigset_t *sigmask);
  • epoll
// timeout最小单位ms,并且rounded up to系统时钟的精度
int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout,
                      const sigset_t *sigmask);
  • eventfd + select/poll/epoll
    一个fd可同时负责读接受事件通知和写触发事件通知

  • signaled + select/poll/epoll
    借助alarm/setitimer/timer_create等触发的SIGALARM,通过signalfd传递到多路复用中

  • pipe + select/poll/epoll
    一端另起线程定时触发,另一端放到多路复用中


分布式系统的时间

扯点其他的东西:-)。时间是个复杂而有意思的东西,在单机上不同处理器不同进程不同线程可以读到同一个系统时钟CLOCK_REALTIME,而且在一定时间范围内t1~t2发生的事件,即使在t1之前,t2之后系统时间与真实时间发生了一定偏移,只要时间戳的相对顺序没乱,那么我们就可以完全确定t1~t2时间戳之间不同线程发生事件的顺序。但是不同机器之间的系统时间总会互相漂移(ntp局域网0.1ms左右,互联网1-50ms左右),导致我们没法直接使用系统时间(google的原子钟也是将一个时间段作为时间点的,只要这个时间段比较小,那么性能应该可以接收),所以需要logic clock以及衍生出来的vector clock或者version number等。

没有全局时钟是分布式系统需要一致性算法的一个重要原因,因为我们没办法根据单机的系统时间戳来判断多台机器之间事件的先后顺序,那么对于一个新的节点,我们要把之前所有的时间atomic broadcast到这个新节点就会出现问题,所以这也是分布式一致性算法(Paxos/Raft/Viewstamp Replication/Zab)解决的一个问题,当然再加上网络的异步,以及无法获知各个节点的全局状态,以及机器crash等各种问题,这些算法往往加入了容错性。

相关文章
|
网络协议 Linux
工作总结之服务器时间不同步导致平台验证失败及Linux系统时间同步方法
在Windwos中,系统时间的设置很简单,界面操作,通俗易懂,而且设置后,重启,关机都没关系。系统时间会自动保存在BIOS时钟里面,启动计算机的时候,系统会自动在BIOS里面取硬件时间,以保证时间的不间断。
242 0
工作总结之服务器时间不同步导致平台验证失败及Linux系统时间同步方法
|
Linux Windows
【看表情包学Linux】Redirect 重定向 | 时间相关指令 | 文件查找 | 打包与压缩(二)
本章仍然是继续对Linux 常用指令进行介绍,将讲解重定向、时间相关的指令、文件查找和打包压缩等指令。我们将初次理解 "Linux下一切皆文件"这一概念,我将通过一个有趣的故事去讲解它。
143 0
【看表情包学Linux】Redirect 重定向 | 时间相关指令 | 文件查找 | 打包与压缩(二)
|
Linux Shell C语言
【看表情包学Linux】Redirect 重定向 | 时间相关指令 | 文件查找 | 打包与压缩(一)
本章仍然是继续对Linux 常用指令进行介绍,将讲解重定向、时间相关的指令、文件查找和打包压缩等指令。我们将初次理解 &quot;Linux下一切皆文件&quot;这一概念,我将通过一个有趣的故事去讲解它。
151 0
【看表情包学Linux】Redirect 重定向 | 时间相关指令 | 文件查找 | 打包与压缩(一)
|
Linux Apache
Linux Command date 显示时间
Linux Command date 显示时间
|
关系型数据库 MySQL Java
Linux系统下java程序获取的时间与系统时间不一致的问题
解决Linux系统下java程序获取的时间与系统时间不一致的问题
1146 0
Linux系统下java程序获取的时间与系统时间不一致的问题
|
Linux
Linux时间编程
Linux时间编程
92 0
|
Linux Apache Windows
Linux安装及管理程序:rpm软件包、源代码安装( 时间最美的地方,就是让你我成为了我们)(二)
Linux安装及管理程序:rpm软件包、源代码安装( 时间最美的地方,就是让你我成为了我们)(二)
111 0
Linux安装及管理程序:rpm软件包、源代码安装( 时间最美的地方,就是让你我成为了我们)(二)
|
Ubuntu Linux Shell
Linux安装及管理程序:rpm软件包、源代码安装( 时间最美的地方,就是让你我成为了我们)(一)
Linux安装及管理程序:rpm软件包、源代码安装( 时间最美的地方,就是让你我成为了我们)(一)
306 0
Linux安装及管理程序:rpm软件包、源代码安装( 时间最美的地方,就是让你我成为了我们)(一)
|
Linux
LINUX chrony同步服务器时间
LINUX chrony同步服务器时间
218 0
LINUX chrony同步服务器时间
|
Linux
【Linux系列】 修改服务器时间
有次服务器重启,导致登录一直失败,定位原因,发现是三台服务器时间不一致导致的。 1,查看时间 date 会显示当前服务时间 2,修改时间,日期加时分秒,日期和时分秒要有个空格 date -s "2020-11-26 14:14:00" 3,仅修改日期 date -s "2020-11-26" 4,仅修改时分秒 date -s "14:14:00" 5,修改后,如果需要写入CMOS hwclock -w ...
140 0
【Linux系列】 修改服务器时间