加入收藏 | 设为首页 | 会员中心 | 我要投稿 济南站长网 (https://www.0531zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

浅析Linux中的时间编程和实现原理(一) Linux应用层的时间编程

发布时间:2016-09-07 14:55:31 所属栏目:Linux 来源:站长网
导读:引子 我们都生活在时间中,但却无法去思考它。什么是时间呢?似乎这是一个永远也不能被回答的问题。然而作为一个程序员,在工作中,总有那么几次我必须思考什么

VIRTUAL 时间是进程执行的时间,Linux 是一个多用户多任务系统,在过去的 1 分钟内,指定进程实际在 CPU 上的执行时间往往并没有 1 分钟,因为其他进程会被 Linux 调度执行,在那些时间内,虽然自然时间在流逝,但指定进程并没有真正的运行。VIRTUAL 时间就是指定进程真正的有效执行时间。比如 5 点 10 分开始的 1 分钟内,进程 P1 被 Linux 调度并占用 CPU 的执行时间为 30 秒,那么 VIRTUAL 时间对于进程 P1 来讲就是 30 秒。此时自然时间已经到了 5 点 11 分,但从进程 P1 的眼中看来,时间只过了 30 秒。

PROF 时间比较独特,对进程 P1 来说从 5 点 10 分开始的 1 分钟内,虽然自己的执行时间为 30 秒,但实际上还有 10 秒钟内核是在执行 P1 发起的系统调用,那么这 10 秒钟也被加入到 PROF 时间。这种时间定义主要用于全面衡量进程的性能,因为在统计程序性能的时候,10 秒的系统调用时间也应该算到 P1 的头上。这也许就是 PROF 这个名字的来历吧。

使用 setitimer Timer 需要了解下面这些接口 API:

int getitimer(int which,struct itimerval *value);

int setitimer(int which,struct itimerval *newval,

struct itimerval *oldval);

itimerval 的定义如下:

struct itimerval {

struct timeval it_interval;

struct timeval it_value;

}

查看本栏目更多精彩内容:http://www.bianceng.cn/OS/Linux/

getitimer 函数得到间隔计时器的时间值,保存在 value 中。

setitimer 函数设置间隔计时器的时间值为 newval. 并将旧值保存在 oldval 中;which 表示使用三个计时器中的哪一个。

itimerval 结构中的 it_value 是第一次调用后触发定时器的时间,当这个值递减为 0 时,系统会向进程发出相应的信号。此后将以 it_internval 为周期定时触发定时器。

给出一个具体的例子:

清单 9,setitmer 例子

void print_info(int signo) 
{ 
 printf(“timer firedn”); //简单的打印,表示 timer 到期
} 
      
void init_sigaction(void) 
{ 
 struct sigaction act; 
 act.sa_handler= print_info; 
 act.sa_flags=0; 
 sigemptyset(&act.sa_mask); 
 sigaction(SIGPROF,&act,NULL); //设置信号 SIGPROF 的处理函数为 print_info
} 
      
void init_time() 
{ 
 struct itimerval value; 
 value.it_value.tv_sec=2; 
 value.it_value.tv_usec=0; 
 value.it_interval=value.it_value; 
 setitimer(ITIMER_PROF,&value,NULL); //初始化 timer,到期发送 SIGPROF 信号
} 
      
int main() 
{ 
 len=strlen(prompt); 
 init_sigaction(); 
 init_time(); 
 while(1); 
 exit(0); 
}

这个程序使用 PROF 时间,每经过两秒 PROF 时间之后就会打印一下 timer fired 字符串。

需要指出:setitimer 计时器的精度为 ms,即 1000 分之 1 秒,足以满足绝大多数应用程序的需要。但多媒体等应用可能需要更高精度的定时,那么就需要考虑使用下一类定时器:POSIX Timer。

POSIX Timer

间隔定时器 setitimer 有一些重要的缺点,POSIX Timer 对 setitimer 进行了增强,克服了 setitimer 的诸多问题:

首先,一个进程同一时刻只能有一个 timer。假如应用需要同时维护多个 Interval 不同的计时器,必须自己写代码来维护。这非常不方便。使用 POSIX Timer,一个进程可以创建任意多个 Timer。

setitmer 计时器时间到达时,只能使用信号方式通知使用 timer 的进程,而 POSIX timer 可以有多种通知方式,比如信号,或者启动线程。

使用 setitimer 时,通知信号的类别不能改变:SIGALARM,SIGPROF 等,而这些都是传统信号,而不是实时信号,因此有 timer overrun 的问题;而 POSIX Timer 则可以使用实时信号。

setimer 的精度是 ms,POSIX Timer 是针对有实时要求的应用所设计的,接口支持 ns 级别的时钟精度。

浅析Linux中的时间编程和实现原理(一) Linux应用层的时间编程

CLOCK_REALTIME 时间是系统保存的时间,即可以由 date 命令显示的时间,该时间可以重新设置。比如当前时间为上午 10 点 10 分,Timer 打算在 10 分钟后到时。假如 5 分钟后,我用 date 命令修改当前时间为 10 点 10 分,那么 Timer 还会再等十分钟到期,因此实际上 Timer 等待了 15 分钟。假如您希望无论任何人如何修改系统时间,Timer 都严格按照 10 分钟的周期进行触发,那么就可以使用 CLOCK_MONOTONIC。

CLOCK_PROCESS_CPUTIME_ID 的含义与 setitimer 的 ITIMER_VIRTUAL 类似。计时器只记录当前进程所实际花费的时间;比如还是上面的例子,假设系统非常繁忙,当前进程只能获得 50%的 CPU 时间,为了让进程真正地运行 10 分钟,应该到 10 点 30 分才允许 Timer 到期。

CLOCK_THREAD_CPUTIME_ID 以线程为计时实体,当前进程中的某个线程真正地运行了一定时间才触发 Timer。

(编辑:济南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读