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("@_@--%d--\n", (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 }

 

posted @ 2018-08-22 23:04  petter_xy  阅读(143)  评论(0编辑  收藏  举报