APUE 第三版 习题 10.5
Posted petter-xy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了APUE 第三版 习题 10.5相关的知识,希望对你有一定的参考价值。
这是书本上的答案:
See ‘‘Implementing Software Timers’’ by Don Libes (C Users Journal, vol. 8, no. 11, Nov. 1990) for an example. A copy of this paper is available online at http://www.kohala.com/start/libes.timers.txt.
我参考上面提到的文档,使用 alarm() 以及time() 简略测试了一下。
仅在在macOS High Sierra10.13.6上测试过,在linux上应该也是没有问题的。
希望可以帮到和我一样是菜鸟的人。
1 #include <stdio.h> 2 #include <time.h> 3 #include <signal.h> 4 #include <unistd.h> 5 6 #define TRUE 1 7 #define FALSE 0 8 9 #define MAX_TIMERS 100 /* number of timers */ 10 typedef time_t TIME; /* how time is actually stored */ 11 ///#define TIME time_t /* how time is actually stored */ 12 #define VERY_LONG_TIME 0xffff /* longest time possible */ 13 14 struct timer { 15 int inuse; /* TRUE if in use */ 16 TIME time; /* relative time to wait */ 17 char *event; /* set to TRUE at timeout */ 18 } timers[MAX_TIMERS]; /* set of timers */ 19 20 void 21 timers_init() { 22 struct timer *t; 23 24 for (t=timers;t<&timers[MAX_TIMERS];t++) 25 t->inuse = FALSE; 26 } 27 28 static TIME s_tt; 29 time_t ttime(time_t *t) 30 { 31 return time(t); 32 } 33 #define time_now ((TIME)(ttime(NULL) - s_tt)) 34 35 struct timer *timer_next = NULL;/* timer we expect to run down next */ 36 static TIME time_timer_set; /* time when physical timer was set */ 37 38 void timers_update(); /* see discussion below */ 39 40 static void disable_interrupts(void) 41 {;} 42 static void enable_interrupts(void) 43 {;} 44 45 #define start_physical_timer alarm 46 47 void 48 timer_undeclare(t) 49 struct timer *t; 50 { 51 disable_interrupts(); 52 if (!t->inuse) { 53 enable_interrupts(); 54 return; 55 } 56 57 t->inuse = FALSE; 58 59 /* check if we were waiting on this one */ 60 if (t == timer_next) { 61 timers_update(time_now - time_timer_set); 62 if (timer_next) { 63 start_physical_timer(timer_next->time); 64 time_timer_set = time_now; 65 } 66 } 67 enable_interrupts(); 68 } 69 70 /* subtract time from all timers, enabling any that run out along the way */ 71 void 72 timers_update(time) 73 TIME time; 74 { 75 static struct timer timer_last = { 76 FALSE /* in use */, 77 VERY_LONG_TIME /* time */, 78 NULL /* event pointer */ 79 }; 80 81 struct timer *t; 82 83 timer_next = &timer_last; 84 85 for (t=timers;t<&timers[MAX_TIMERS];t++) { 86 if (t->inuse) { 87 if (time < t->time) { /* unexpired */ 88 t->time -= time; 89 if (t->time < timer_next->time) 90 timer_next = t; 91 } else { /* expired */ 92 /* tell scheduler */ 93 *t->event = TRUE; 94 t->inuse = 0; /* remove timer */ 95 } 96 } 97 } 98 99 /* reset timer_next if no timers found */ 100 if (!timer_next->inuse) timer_next = 0; 101 } 102 103 struct timer * 104 timer_declare(time,event) 105 unsigned int time; /* time to wait in 10msec ticks */ 106 char *event; 107 { 108 struct timer *t; 109 110 disable_interrupts(); 111 112 for (t=timers;t<&timers[MAX_TIMERS];t++) { 113 if (!t->inuse) break; 114 } 115 116 /* out of timers? */ 117 if (t == &timers[MAX_TIMERS]) { 118 enable_interrupts(); 119 return(0); 120 } 121 122 /* install new timer */ 123 t->event = event; 124 t->time = time; 125 if (!timer_next) { 126 /* no timers set at all, so this is shortest */ 127 time_timer_set = time_now; 128 129 start_physical_timer((timer_next = t)->time); 130 } else if ((time + time_now) < (timer_next->time + time_timer_set)) { 131 /* new timer is shorter than current one, so */ 132 timers_update(time_now - time_timer_set); 133 time_timer_set = time_now; 134 start_physical_timer((timer_next = t)->time); 135 } else { 136 /* new timer is longer, than current one */ 137 } 138 t->inuse = TRUE; 139 enable_interrupts(); 140 return(t); 141 } 142 143 void 144 timer_interrupt_handler(int m) { 145 timers_update(time_now - time_timer_set); 146 147 /* start physical timer for next shortest time if one exists */ 148 if (timer_next) { 149 time_timer_set = time_now; 150 start_physical_timer(timer_next->time); 151 printf("@[email protected]%d-- ", (int)timer_next->time); 152 } 153 } 154 155 int 156 main(void) 157 { 158 s_tt = time(NULL); 159 char _4s, _5s, _11s, _19s; 160 161 signal(SIGALRM, timer_interrupt_handler); 162 start_physical_timer(1); 163 164 timer_declare(4, &_4s); 165 timer_declare(5, &_5s); 166 timer_declare(11, &_11s); 167 timer_declare(19, &_19s); 168 timer_declare(20, &_19s); 169 timer_declare(21, &_19s); 170 timer_declare(23, &_19s); 171 172 while(1); 173 174 return 0; 175 }
以上是关于APUE 第三版 习题 10.5的主要内容,如果未能解决你的问题,请参考以下文章