Linux内核|实验五 内核的定时机制实验
来源:互联网 发布:阿里云系统电视root 编辑:程序博客网 时间:2024/06/08 11:03
1 实验目的
本实验是练习怎样编写调用内核的时间测量功能为应用程序测量和精确定时。通过这个实验我们可以进一步理解 Linux
内核的定时机制及其数据结构以及怎样从用户空间去访问内核空间的时间数据。
2 实验内容
A 在用户态编写一个程序,该程序设定一个定时器,在时间到期的时候做出某种可观察的响应(方法不限)。
B 用定时器 ITIMER_REAL
实现gettimeofday
的功能。使其一秒钟产生一个信号,计算已经过的秒数。
C 记录一个进程运行时所占用的real time
,cpu time
, user time
, kernel time
。
3 实验说明
1) 系统时间的获取和内核定时机制
从用户空间去获取系统时间数据需要以下基本代码:
#include <sys/time>…struct timeval{long tv_sec; //从 1970-1-1 12:到现在经过的秒数long tv_usec;//从从上 1 秒到现在经过的微秒数} theTime;…gettimeofday(&theTime,NULL); //获取系统时间的系统调用…
每个进程使用的各种定时器需要Linux
的内部定时器。内部定时器可以跟踪记录3
种不同类型的定时机制,它们反映了不同时间的划分。这三种定时机制具有不同的作用和应用,分别是: ITIMER_REAL
:反映进程经过的实际时间,这种定时器到时后发 SIGALRM
信号。它与struct task_struct
结构中的it_real_value
和 it_real_incr
字段有关。
ITIMER_VIRTUAL:反映进程经过的虚拟时间,只有相关进程正在执行时该时间才会增加。这种定时器到时后发 SIGVTALRM 信号。与
struct task_struct 结构中的
it_virt_value和
it_virt_incr字段有关
ITIMER_PROF:反映进程经过的虚拟时间加上内核为相关进程执行工作的时间之和。这种定时 器 到 时 后 发
SIGPROF 信 号 。 与
struct task_struct 结 构 中 的
it_prof_value 和
it_prof_incr `字段有关。
每个定时器需要周期性的设定一个初始时间值,之后递减计数到 0 后引发定时中断,产生超时信号通知对应进程定时器时间到,然后定时器重新从设置的初始值再次开始递减计数。
2) 定时器的使用
定时器使用:定时器的使用只须执行一些初始化工作,设置一个超时时间,指定超时发生后执行的函数,然后激活定时器就可以了。
定时器的使用步骤
初始化,
设置一个超时时间,
指定超时发生时执行的函数,
激活定时器。
3) 使用定时器时的函数
(1) 初始化:三种定时器都使用setitimer()系统调用进行初始化:
#include <sys/time.h>…函数setitimer(int timerType ,//定时器类型const struct itimerval *value, //定时器初始的和当前的秒数和毫秒数struct itimerval *oldValue //该参数可不做处理)结构体struct itimerval{struct timeval it_it_interval; //下一次定时初值。为0定时器停止struct timeval it_value //定时器当前值} ;
(2) 三种定时器都使用getitimer()系统调用获取定时器当前值:
#include <sys/time.h>…函数getitimer(int timerType ,//定时器类型const struct itimerval *value, //定时器当前的秒数和毫秒数)
(3) 各类定时器到时的信号处理函数可以使用系统调用函数指定:
sighandler_t signal(int signum, //信号类型sighandler_t handler //信号处理函数名);
4 实验程序:
A 在用户态编写一个程序,该程序设定一个定时器,在时间到期的时候做出某种可观察的响应(方法不限)。
设计思路:
设置定时器 ITIMER_REAL
间隔为一秒钟。并为计时到时设定信号处理程序,使其输出当前所记时间。定时3秒,计时结束,给出提示、终止程序。
程序源代码清单:
/****test3.c*****/#include <sys/time.h>#include <stdio.h>#include <stdlib.h>#include <signal.h>static void sighandle(int);static int second = 0;int main(){struct itimerval v;signal(SIGALRM,sighandle);v.it_interval.tv_sec = 1;v.it_interval.tv_usec = 0;v.it_value.tv_sec = 1;v.it_value.tv_usec = 0;setitimer(ITIMER_REAL,&v,NULL);for(;;);}static void sighandle(int s){second++;if(second<=3)printf("%d\r",second);else abort();fflush(stdout);}
运行结果:
B 用定时器ITIMER_REAL
实现gettimeofday
的功能。使其一秒钟产生一个信号,计算已经过的秒数。
设计思路:
设置定时器ITIMER_REAL
间隔为一秒钟。并为计时到时设定信号处理程序,即 singal(SIGALRM,⋯)
,使其输出当前所记时间。
程序源代码清单:
/****test1.c*****/#include <sys/time.h>#include <stdio.h>#include <signal.h>static void sighandle(int);static int second = 0;int main(){struct itimerval v;signal(SIGALRM,sighandle);v.it_interval.tv_sec = 1;v.it_interval.tv_usec = 0;v.it_value.tv_sec = 1;v.it_value.tv_usec = 0;setitimer(ITIMER_REAL,&v,NULL);for(;;);}static void sighandle(int s){second++;printf("%d\r",second);fflush(stdout);}
运行结果:每隔一秒结果+1
C 记录一个进程运行时所占用的real time
, cpu time
, user time
, kernel time
。
设计思路:
任务开始前设置好定时器ITIMER_REAL
,ITIMER_VIRTUAL
,ITIMER_PROF
,即 其相应的信号处理程序。在任务执行过程中内核定时器通过产生等间隔的信号来记录进程所需的各种时间参量,并在任务结束后打印出来。
程序源代码清单 :
/************test2.c**********/#include <sys/time.h>#include <stdio.h>#include <signal.h>static void sighandle(int);static long realsecond = 0;static long vtsecond = 0;static long profsecond = 0;static struct itimerval realt,virtt,proft;int main(){struct itimerval v;int i,j;long moresec,moremsec,t1,t2;signal(SIGALRM,sighandle);signal(SIGVTALRM,sighandle);signal(SIGPROF,sighandle);v.it_interval.tv_sec = 10;v.it_interval.tv_usec = 0;v.it_value.tv_sec = 10;v.it_value.tv_usec = 0;setitimer(ITIMER_REAL,&v,NULL);setitimer(ITIMER_VIRTUAL,&v,NULL);setitimer(ITIMER_PROF,&v,NULL);for(j= 0;j<1000;j++){for(i= 0;i<500;i++){printf("********\r");fflush(stdout);}}getitimer(ITIMER_PROF,&proft);getitimer(ITIMER_REAL,&realt);getitimer(ITIMER_VIRTUAL,&virtt);printf("\n");moresec = 10 - realt.it_value.tv_sec;moremsec = (1000000 - realt.it_value.tv_usec)/1000;printf("realtime = %ld sec, %ld msec\n",realsecond+moresec,moremsec);moresec = 10 - proft.it_value.tv_sec;moremsec = (1000000 - proft.it_value.tv_usec)/1000;printf("cputime = %ld sec, %ld msec\n",profsecond+moresec,moremsec);moresec = 10 - virtt.it_value.tv_sec;moremsec = (1000000 - virtt.it_value.tv_usec)/1000;printf("usertime = %ld sec, %ld msec\n",vtsecond+moresec,moremsec);t1 = (10 - proft.it_value.tv_sec)*1000 + (1000000 - proft.it_value.tv_usec)/1000 +profsecond*10000;t2 = (10 - virtt.it_value.tv_sec)*1000 + (1000000 - virtt.it_value.tv_usec)/1000 +vtsecond*10000;moresec = (t1 - t2)/1000;moremsec = (t1 - t2) % 1000;printf("kerneltime = %ld sec, %ld msec\n",moresec,moremsec);fflush(stdout);}static void sighandle(int s){switch(s){case SIGALRM:realsecond+=10;break;case SIGVTALRM:vtsecond+=10;break;case SIGPROF:profsecond+=10;break;default :break;}}
运行结果:
- Linux内核|实验五 内核的定时机制实验
- 内核的定时机制实验
- Linux内核分析:实验五
- Linux内核分析:实验五
- Linux内核分析实验五
- linux内核实验五实现过程
- <实验五>linux操作系统内核的工作过程
- Linux内核修改实验
- Linux内核修改实验
- Linux内核剪裁实验
- 嵌入式Linux内核实验
- linux内核实验0
- Linux内核实验
- linux 2.6内核的移植实验
- Linux内核实验要注意的地方
- Linux内核分析 实验五:分析system_call中断处理过程
- Linux内核分析 实验五:分析system_call中断处理过程
- Linux内核移植实验之---内核的配置和编译
- C语言运算符优先级
- 冒泡排序
- 阿里编程测试 小猴子的问题
- hdu 3746 kmp next求最小循环节
- 文字排版 (Coursera 程序设计与算法 专项课程2 C程序设计进阶 李戈;OpenJudge)
- Linux内核|实验五 内核的定时机制实验
- 移动前端开发与WEB前端开发有什么联系与区别?
- 蓝桥杯练习系统第十二题,十六进制转十进制(脱坑版)
- 解决Eclipse字符编码改为UTF-8后乱码问题
- 基于redis的延迟消息队列设计
- IDEA配置pom.xml
- PHP基础教程-28 课后作业07
- Windows与Mac下安装tcnativie-1.dll的流程以及Mac下安装Homebrew流程
- Spring框架-基于注解的组件扫描