![[code.nginx] Nginx的时间管理,第1张 [code.nginx] Nginx的时间管理,第1张](/aiimages/%5Bcode.nginx%5D+Nginx%E7%9A%84%E6%97%B6%E9%97%B4%E7%AE%A1%E7%90%86.png)
在Linux平台上获取系统时间的方法有很多,比如使用time()函数、gettimeofday()函数和localtime()函数等,大部分函数本质上都是通过系统调用来获取时间的。但是使用系统调用时,有一个问题需要特别关注,就是系统调用开销的问题。
Nginx服务器程序在获取系统时间时,本质上使用的是gettimeofday函数,该函数是C语言库提供的函数,从严格意义上来讲,该函数不也是系统调用,但它是对系统调用sys_gettimeofday()的封装,因此一般也就认为它是一个系统调用了。
大家都知道,Linux平台上程序函数调用可以分为库调用和系统调用两大类,这里不过多的解释这两种机制的不同,主要是明确系统调用与库调用相比,时间成本是相当巨大的。程序执行一次系统调用将至少经过一下步骤:
在Linux平台上使用C语言进行程序设计时,为了精确获取系统时间,我们经常会使用gettimeofday()这个函数。该函数的原型为:
调用该函数后,当前的时间将用timeval结构体返回,时间可以精确到微秒。当地时区的信息则放在timezone结构体中。timeval结构体的定义为:
gettimeofday()函数在执行过程中,一般情况下实际上是调用了另一个函数sys_gettimeofday(),该函数才是名副其实的系统调用,通过该调用就可以获取保存在系统内核中的时间信息。在实际程序设计中是不提倡频繁使用gettimeofday()函数的。
vsyscall方式在内存中创建了一个内核态的共享页面,它的数据由内核来维护,但这块区域用户态也有权限访问,通过这样的机制,不经过系统中断和陷入内核也能获取一些内核信息。x86_64体系上使用vsyscall方式实现了gettimeofday()的功能,这样系统开销比普通的系统调用要小的多。
Nginx服务器重视程序的高效运行,Nginx程序采取缓存时间的方法来减少对gettimeofday()的调用,并且每个工作进程会自行维护时间缓存。Nginx的时间缓存一般会赋值给一下四种变量,更新缓存时是同步更新的。
Nginx服务器更新时间缓存的两个函数是ngx_time_update()和ngx_time_sigsafe_update(),具体的实现的源码都在/nginx/src/core/ngx_timec中可以找到。我们分别来分析一下它们的源码。
1ngx_time_update()
该函数是Nginx服务器时间管理的核心函数。更新时间缓存的过程实际上是一个写缓存的过程,Nginx服务器为了解决信号处理过程中更新时间缓存产生的数据一致性的问题,需要使用原子变量ngx_time_lock进行写加锁。
2ngx_time_update()的调用
该函数的调用时机主要有三个:一是在Nginx服务器主进程捕捉、处理完一个信号返回的时候。二是在缓存索引管理进程中调用该函数,用于标记缓存数据的时间属性。三是在Nginx服务器工作进程中在进行事件处理时调用了该函数。主要是第三种情况对该函数的调用频率较高。
epoll_wait()函数用于等待事件的产生,执行epoll_wait()函数返回后会调用ngx_time_update()函数更新时间缓存。当epoll机制通知有事件到达或者epoll机制超时退出时,Nginx服务器程序就会更新一次缓存时间。然后调用各个事件对应的处理函数处理事件。
指令timer_resolution用于设置执行两次缓存时间更新工作之间的间隔时间。该参数设置的越大,则对系统调用gettimeofday()的使用频率就越低,但缓存时间的精度也就越低。该指令的语法结构为:
其中的Interval参数就是更新时间间隔,默认值为100ms。该指令只能在Nginx配置文件的全局块中进行设置。
lpKernelTime 内核时间:指明线程执行 *** 作系统代码已经经过了多少个100ns的CPU时间
红线为内核时间。是表明处理器工作时间百分比的图表。该计数器是处理器活动的主要指示器。查看该图表可以知道您当前使用的处理时间是多少。如果您的计算机看起来运行较慢,该图表就会显示较高的百分比。
没危险!放心
首先,你这样问,说明你不理解jiffies,jiffies应该说不是时间,jiffies的增加,是根据HZ的值变化而变化的。以时下linux kernel来说:1s=jiffies/HZ(即1秒=jiffies/HZ);在asm_i386中,HZ被定义为一个常,且为1000一般在内核中定义超时是这样用,如:xxx_timerexpires = jiffies+HZ/100;这个定义表示超时时间为10ms,如果超过个时间就处理中断函数或者做你想做的事当然HZ的分母你可以定为别的数。如HZ/1000等
在编译Linux内核,配置时:make menuconfig ---> Kernel hacking --> show timing information on printks
当选中这个选项后,启动内核,会在日志信息前面加上时间戳。
从下面的输出可以看出,时间精确到微秒(us)。
如下:
-------------------------------------------------------------------------------------------
Uncompressing Linux done, booting the kernel
[ 0000000] Linux version 26357+ (bshen@bamboo) (gcc version 441 (Sourcery G++ Lite 2010q1-202) ) #109 PREEMPT Mon Nov 14 15:11:15 CST 2011
[ 0000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
[ 0000000] CPU: VIVT data cache, VIVT instruction cache
--------------------------------------------------------------------------------------------
Linux内核切换线程时间在微秒级别,几十微秒。
1 查看需要更新的内核命令:
apt-cache search linux#该命令将会显示所有可以获取的内核
2 安装内核,假设要安装的内核为2639-0,则使用下面的命令
sudo apt-get install linux-headers-2639-0-generic linux-image-2639-0-generic#安装后,reboot即可,重启后,既是以新内核启动。
以上就是关于[code.nginx] Nginx的时间管理全部的内容,包括:[code.nginx] Nginx的时间管理、什么是内核时间、内核定时器 jiffies的时间是多少等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)