Linux定时器
- 题目
- 相关概念
- setitimer
- 计时器
- 源码
题目
相关概念
setitimer
Linux 系统为每个进程提供三个间隔计时器,每个计时器在不同的时间域递减。当任何计时器
到期时,向进程发送一个信号,然后计时器(可能)重新启动。
ITIMER_REAL 定时器运行的时间就是总运行时间,
ITIMER_PROF 定时器的运行时间就是 CPU 花在该进程上的所有时间。
ITIMER_VIRTUAL定时器运行的时间是进程在用户模式的运行时间。
复制代码
1
2
3ITIMER_PROF 定时器的运行时间减去ITIMER_VIRTUAL 定时器的运行时间 就是进程在核心模式的运行时间。
计时器
复制代码
1
2
3
4
5
6
7
8
9
10
11/*参数 结构体 itimerval */ struct itimerval { struct timeval it_interval; /* 第一次触发定时器后,每次触发定时器周期时间值 */ struct timeval it_value; /* 第一次触发定时器时间值 */ }; struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ }
复制代码
1
2int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
参数 which:(可选值如下)
ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。
ITIMER_VIRTUAL:以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算。它送出SIGPROF信号。
参数 *new_value: 用于对定时器的时间进行配置,即配置什么时候触发定时器
参数 *old_value: 获取上一次配置的时间参数值
源码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/shm.h> #include<signal.h> #include <stdlib.h> #include<time.h> #include<sys/time.h> #include <fcntl.h> #include <limits.h> #include <sys/types.h> #include <sys/wait.h> static void par_sig(int signo); /*父进程的信号处理函数*/ static void c1_sig(int signo); /*子进程 1 的信号处理函数*/ /*用于分别记录父,子 1 进程 real time 过的总秒数*/ static long p_realt_secs=0,c1_realt_secs=0; /*用于分别记录父,子 1进程 virtual time 过的总秒数*/ static long p_virtt_secs=0, c1_virtt_secs=0; /*用于分别记录父,子 1 进程 proft time 过的总秒数*/ static long p_proft_secs=0,c1_proft_secs=0; /*用于分别取出父,子 1 进程的 real timer 的值*/ static struct itimerval p_realt,c1_realt; /*用于分别取出父,子 1,子 2 进程的 virtual timer 的值*/ static struct itimerval p_virtt,c1_virtt; /*用于分别取出父,子 1进程的 proft timer 的值*/ static struct itimerval p_proft,c1_proft; int main() { long unsigned fib=0; pid_t pid1,pid2; unsigned int fibarg=39; int status; struct itimerval v; long moresec,moremsec,t1,t2; pid1=fork(); if(pid1==0) { /*设置子进程 1 的信号处理函数和定时器初值*/ signal(SIGALRM,c1_sig); signal(SIGVTALRM,c1_sig); signal(SIGPROF,c1_sig); 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); /* operation 在此处可以添加任意操作,可以统计此进程的时间 */ /*取出子进程 1 的定时器值*/ getitimer(ITIMER_PROF,&c1_proft); getitimer(ITIMER_REAL,&c1_realt); getitimer(ITIMER_VIRTUAL,&c1_virtt); /*通过定时器的当前值和各信号发出的次数计算子进程 1 总共用的 real time,cpu time,user time 和 kernel time。moresec 和 moremsec 指根据定时器的当前值计算 出的自上次信号发出时过去的 real time,cpu time,user time 和 kernel time。计算 kernel time 时,moresec 和 moremsec 为 kernel time 的实际秒数+毫秒数*/ moresec=9-c1_realt.it_value.tv_sec; moremsec= (1000000-c1_realt.it_value.tv_usec)/1000; printf("Child 1 fib=%ld , real time=%ld sec,%ldmsecn",fib,c1_realt_secs+moresec,moremsec); moresec=9-c1_proft.it_value.tv_sec; moremsec=(1000000-c1_proft.it_value.tv_usec)/1000; printf("Child 1 fib=%ld , cpu time=%ld sec,%ldmsecn",fib,c1_proft_secs+moresec,moremsec); moresec=9-c1_virtt.it_value.tv_sec; moremsec=(1000000-c1_virtt.it_value.tv_usec)/1000; printf("Child 1 fib=%ld , user time=%ld sec,%ldmsecn",fib,c1_virtt_secs+moresec,moremsec); t1=(9-c1_proft.it_value.tv_sec)*1000+(1000000-c1_proft.it_value.tv_usec)/1000+c1_proft_secs*10000; t2=(9-c1_virtt.it_value.tv_sec)*1000+(1000000-c1_virtt.it_value.tv_usec)/1000+c1_virtt_secs*10000; moresec=(t1-t2)/1000;moremsec=(t1-t2)%1000; printf("Child 1 fib=%ld , kernel time=%ld sec,%ld msecn",fib,moresec,moremsec); fflush(stdout); exit(0); } else { /*设置父进程的信号处理函数和定时器初值*/ signal(SIGALRM,par_sig); signal(SIGVTALRM,par_sig); signal(SIGPROF,par_sig); 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); /* operation 在此处可以添加任意操作,可以统计此进程的时间 */ /*取出父进程的定时器值*/ getitimer(ITIMER_PROF,&p_proft); getitimer(ITIMER_REAL,&p_realt); getitimer(ITIMER_VIRTUAL,&p_virtt); /*通过定时器的当前值和各信号发出的次数计算子进程 1 总共用的 real time,cpu time,user time 和 kernel time。moresec 和 moremsec 指根据 定时器的当前值计算出的自上次信号发出时过去的 real time,cpu time,user time 和 kernel time。计算 kernel time 时,moresec 和 moremsec 为 kernel time 的实际秒数+毫秒数*/ moresec=9-p_realt.it_value.tv_sec; moremsec=(1000000-p_realt.it_value.tv_usec)/1000; printf("Parent fib=%ld , real time=%ld sec,%ldmsecn",fib,p_realt_secs+moresec,moremsec); moresec=9-p_proft.it_value.tv_sec; moremsec=(1000000-p_proft.it_value.tv_usec)/1000; printf("Parent fib=%ld , cpu time=%ld sec,%ldmsecn",fib,p_proft_secs+moresec,moremsec); moresec=9-p_virtt.it_value.tv_sec; moremsec=(1000000-p_virtt.it_value.tv_usec)/1000; printf("Parent fib=%ld , user time=%ld sec,%ldmsecn",fib,p_virtt_secs+moresec,moremsec); t1=(9-p_proft.it_value.tv_sec)*1000+(1000000-p_proft.it_value.tv_usec)/1000+p_proft_secs*10000; t2=(9-p_virtt.it_value.tv_sec)*1000+(1000000-p_virtt.it_value.tv_usec)/1000+p_virtt_secs*10000; moresec=(t1-t2)/1000; moremsec=(t1-t2)%1000; printf("Parent fib=%ld , kernel time=%ld sec,%ldmsecn",fib,moresec,moremsec); fflush(stdout); waitpid(0,&status,0); waitpid(0,&status,0); exit(0); printf("this line should never be printedn"); } } /*父进程信号处理函数;每个 timer 过 10 秒减为 0,激活处理函数一次,相应的计数器加 10*/ static void par_sig(int signo) { switch(signo) { case SIGALRM: p_realt_secs+=10; break; case SIGVTALRM: p_virtt_secs+=10; break; case SIGPROF: p_proft_secs+=10; break; } } /*子进程 1 的信号处理函数,功能与父进程的信号处理函数相同*/ static void c1_sig(int signo) { switch(signo) { case SIGALRM: c1_realt_secs+=10; break; case SIGVTALRM: c1_virtt_secs+=10; break; case SIGPROF: c1_proft_secs+=10; break; } }
最后
以上就是独特爆米花最近收集整理的关于操作系统课设-统计进程的时间-Linux定时器题目相关概念源码的全部内容,更多相关操作系统课设-统计进程内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复