学校网站建设与维护,南京做网站工作室,wordpress时间轴归档,河西集团网站建设1. Linux中time相关概念1.1 real time指的是实际流逝的时间#xff0c;又称为Wall Clock Time(墙上时间)。比如#xff0c;time命令统计出的real time指的是该进程从开始运行到运行结束所消耗的时间。在这段时间内不仅仅执行了该进程#xff0c;其他进程的时间片也得到了轮转…1. Linux中time相关概念1.1 real time指的是实际流逝的时间又称为Wall Clock Time(墙上时间)。比如time命令统计出的real time指的是该进程从开始运行到运行结束所消耗的时间。在这段时间内不仅仅执行了该进程其他进程的时间片也得到了轮转。1.2 process time指的是执行某进程所消耗的CPU time。CPU time指的是执行该进程有关代码所花的时间分为User CPU time和System CPU time两部分。User CPU time指的是在用户态执行该进程的代码所花费的时间不统计该进程阻塞花费的时间也不统计其他进程的时间片。System CPU time指的是在内核态执行该进程的代码所花费的时间不统计该进程阻塞花费的时间也不统计其他进程的时间片。。其实我觉得“该进程阻塞花费的时间”和“其他进程的时间片” 是一个意思。因为进程阻塞时内核会调度其他进程执行所以我觉得这两个是一个意思。需要注意Real time ! User CPU time System CPU time。两个原因对于多核处理器上跑的多线程程序会出现real time User CPU time System CPU time的情况。毕竟计算机上不止一个进程在跑real time中还统计了其他进程的时间片。1.3 hardware clock指计算机中电池供电的硬件时钟记录了当前的墙上时间又被称为RTC(Real Time Clock)。内核在启动时会读取该硬件时钟来初始化内核中的软件时钟(Software Clock)。1.4 software clock, HZ, and jiffysoftware clock指的是内核维护的软件时钟。需要设置timeout的系统调用(例如selectsigtimedwait)以及测量cpu time的系统调用(例如getrusage)的准确度(accuracy)由软件时钟的精度(precision / resolution)决定。Linux内核维护的软件时钟的精度是jiffy也就是说软件时钟用jiffy衡量时间。jiffy对应的real time由内核中的常量HZ决定jiffy 1 / HZ。HZ的值可人为调节可取的值在不同的内核版本和不同的硬件平台下也不一样。在i386平台下内核版本2.6.0后HZ的取值可以达到1000意味着jiffy对应0.001秒。那么为什么设置timeout的系统调用和测量cpu time的系统调用的准确度受jiffy的限制呢原因如下。cpu里面有可编程间隔定时器PIT(Programmable interval timer)目前x86-64/arm/8051-based的绝大多数cpu/mcu都是内置PIT的PIT以一个可调节的时间间隔即jiffy触发时钟中断使得操作系统的时钟中断处理程序可以可调节地周期性运行。时钟中断处理程序负责维护所有的软件定时器在当前进程的时间片用光或有定时器触发时执行进程调度(线程调度)。时钟中断处理程序还负责维护软件时钟。因此软件时钟的精度以及timer相关系统调用的精度都由jiffy限制。1.5 High-resolution timers在内核版本2.6.21之前timer and sleep system calls 的准确度由jiffy限制。自从内核版本2.6.21之开始Linux开始支持高精度定时器(High-resolution timers, HRTs)。在支持HRTs的系统上timer and sleep system calls 的准确度不再受jiffy限制可以达到硬件级别的准确度。可以通过clock_getres()返回的时钟的精度判断系统是否支持高精度定时器。sleep system calls 包括1.6 EpochUnix系统使用从1970-01-01 00:00:00 0000 (UTC)到现在的秒数表示时间。1970-01-01 00:00:00 0000 (UTC)这个时间点称为Epoch。2. 获取时间2.1 结构体目前所知表示时间只有两种结构体timeval和timespec它们的区别主要是精度不同有些函数的参数使用timeval有些使用timespec。struct timeval {time_t tv_sec; /* seconds */suseconds_t tv_usec; /* microseconds */};struct timespec {time_t tv_sec; /* seconds */long tv_nsec; /* nanoseconds */};2.2 函数Linux中获取时间的函数有多种这里我只提gettimeofday()和clock_gettime()。2.2.1 gettimeofday()int gettimeofday(struct timeval *tv, struct timezone *tz);gettimeofday()是系统调用用于获取从Epoch开始到现在的时间精度是微秒。各种资料表明gettimeofday()读取的是内核中的xtime变量的值xtime每个时钟中断更新一次其精度受限于jiffy。既然是这样那么为什么gettimeofday()的精度是微秒呢经过我查阅资料jiffy虽然会影响软件时钟的精度但是gettimeofday()不是简单地读取xtimegettimeofday()的实现仍然会依赖于硬件时钟。更具体的解释请查看[7]。我个人认为gettimeofday()的精度和内核是否支持高精度定时器并没有关系。一个是读取时间一个是定时器两者是不同的概念。查阅资料没发现有人明确讲这个以后遇到了再做补充吧。2.2.2 clock_gettime()int clock_getres(clockid_t clk_id, struct timespec *res);int clock_gettime(clockid_t clk_id, struct timespec *tp);int clock_settime(clockid_t clk_id, const struct timespec *tp);通过上面的接口可以访问多个时钟这些时钟表示不同的含义。上面的接口中用户需要通过clk_id指定对哪个时钟进行操作。其中clock_gettime()可以获取指定时钟的时间clock_getres()可以获取指定时钟的精度。这些时钟的更新原理并不清楚但是可以肯定的是其精度和内核是否支持高精度定时器密切相关。因为多个资料提到可以使用clock_getres()得到的精度判断内核是否支持高精度定时器。clk_id的值CLOCK_REALTIME 墙上时间真实的时间但是受系统时钟(system clock)改变的影响例如用户调用adjtime函数改变了系统时钟那么该墙上时间就会随之改变。CLOCK_MONOTONIC 该时钟用于测量相对的real time该时钟和实际的时间相同的速度流逝并且不被系统时钟(system clock)的手动/自动改变所影响。CLOCK_PROCESS_CPUTIME_ID 用于测量进程所用的CPU time。CLOCK_THREAD_CPUTIME_ID 用于测量线程所用的CPU time。int timer_create (clockid_t clockid, struct sigevent *evp, timer_t *timerid);该系统调用用于创建定时器参数clk_id用于指定该定时器使用的时钟。该系统调用创建的定时器是高精度定时器。因此我们使用clock_getres()得到的精度肯定应该小于jiffy。这就印证了之前说的可以通过clock_getres()查看时钟的精度来判断内核是否支持高精度定时器。我自己使用clock_getres()测试的各时钟的精度是1ns表示内核支持高精度定时器。3. 某些系统调用的time accuracysleep的参数是秒accuracy可以达到1秒。Linux下其由nanosleep实现usleep的参数是微秒但是有人说其accuracy不是微秒说它仍是由时间中断实现的本人还没有找到资料证明usleep究竟有没有使用HRTs。nanosleep的参数是纳秒其由HRTs实现使用CLOCK_MONOTONIC测量时间不受jiffy限制accuracy具体可以达到多少不清楚但是应该可以达到微秒级别。select的参数是微秒别人测试accuracy可以达到微秒有人说其由HRTs实现但是本人未找到更具体的资料。因此选择延时函数应该一步到位直接用nanosleep。4. Reference