#include <stdio.h> #include <unistd.h> #include "alarm.h" static void any1(void *s) { printf("%s", (char *)s); fflush(NULL); } static void any2(void *s) { printf("%s", (char *)s); fflush(NULL); } static void any3(void *s) { printf("%s", (char *)s); fflush(NULL); } int main(void) { anytimer_alarm(3, any1, "hello"); anytimer_alarm(2, any2, "world"); anytimer_alarm(5, any3, "apue"); /* **world*hello**apue****** */ while (1) { write(1, "*", 1); sleep(1); } return 0; }
#include <stdlib.h> #include <signal.h> #include <errno.h> #include <sys/time.h> #include "alarm.h" typedef struct{ sec_t sec; anyfun_t anyfun; void *argp; }alarm_t; static alarm_t *alrm[MAX_ALARM]; struct sigaction oldact; struct itimerval olditi; static void handler(int s) { int i; anyfun_t fun; for(i = 0; i < MAX_ALARM; i++){ if(alrm[i]){ alrm[i]->sec -= 1; if(alrm[i]->sec == 0){ fun = alrm[i]->anyfun; fun(alrm[i]->argp); free(alrm[i]); alrm[i] = NULL; } } } } static void mod_unload(void) { sigaction(SIGALRM, &oldact, NULL); setitimer(ITIMER_REAL, &olditi, NULL); } static void mod_load(void) { struct sigaction act; struct itimerval iti; act.sa_handler = handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGALRM, &act, &oldact); iti.it_interval.tv_sec = 1; iti.it_interval.tv_usec = 0; iti.it_value.tv_sec = 1; iti.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &iti, &olditi); atexit(mod_unload); } static int get_pos(void) { for(int i = 0; i < MAX_ALARM; i++){ if(NULL == alrm[i]) return 1; } return -1; } static int alarm_init(int s, anyfun_t fun, void *arg) { alarm_t *p = NULL; int pos = get_pos(); if(pos < 0) return -2; mod_load(); p = malloc(sizeof(*p)); if(p = NULL) return -1; p->sec = s; p->anyfun = fun; p->argp = arg; alrm[pos] = p; return pos; } int anytimer_alarm(sec_t sec, anyfun_t anyfun, void *arg) { int it; it = alarm_init(sec, anyfun, arg); if(it == -1) return -ENOMEM; else if(it == -2) return -ENOBUFS; return it; }
#ifndef __ALARM_H #define __ALARM_H #define MAX_ALARM 1024 typedef unsigned int sec_t; typedef void (*anyfun_t)(void *); int anytimer_alarm(sec_t sec, void (*anyfun)(void *), void *arg); #endif