UEA20181224 郭恩赐 作业2019 3 22
实现功能
信号设定闹钟,可以一次设定多个闹钟,谁的时间短谁先触发,并执行相应的操作
运行结果
gec@tbf$ ./a.out
**world*hello**apue********
main.c
#include <stdio.h> #include "anytimeralarm.h" #include<unistd.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; }
anytimeralarm.h
#ifndef __ANYTIMERALARM_H #define __ANYTIMERALARM_H #define MAX_ALARM 1024 //最多可同时设置1024个闹钟 //typedef 秒是无符号整形的 typedef unsigned int sec_t; //定义函数指针类型 anyfun_t typedef void (*anyfun_t)(void *); /* 函数功能:设定倒计时时间执行相应程序,多次设定时间短的先执行 参数 1,sec 是unsigned int sec设定闹钟倒计时的秒数; 2,anyfun是函数指针,参数任意类型指针,无返回值。 3,arg 是传给anyfun函数的参数。 成功返回值 0 ;失败返回 -1 */ int anytimer_alarm(sec_t sec,void (*anyfun)(void *),void *arg); #endif
anytimeralarm.c
1 #include<stdlib.h> 2 #include<sys/time.h> 3 #include<signal.h> 4 #include<errno.h> 5 #include"anytimeralarm.h" 6 7 //定义每个闹钟的结构 8 typedef struct { 9 sec_t sec; 10 // void (*anyfun)(void*); 11 anyfun_t anyfun; 12 void *argp; 13 }alarm_t; 14 15 //定义一个函数指针最多存放1024个闹钟 16 static alarm_t *jobs[MAX_ALARM]; 17 18 //定义设置信号和闹钟之前的状态 19 struct sigaction oldact; 20 struct itimerval oldtmv; 21 22 //信号响应处理函数 23 static void handler(int s) 24 { 25 int i; 26 anyfun_t fun; 27 for(i = 0;i<MAX_ALARM;i++){ 28 if(jobs[i]){ 29 jobs[i]->sec -= 1 ; 30 if(jobs[i]->sec == 0){ 31 fun = jobs[i]->anyfun; 32 fun(jobs[i]->argp); 33 34 free(jobs[i]); 35 jobs[i] = NULL; 36 } 37 } 38 } 39 } 40 41 //卸载模块 42 static void mod_unload(void) 43 { 44 sigaction(SIGALRM,&oldact,NULL); 45 setitimer(ITIMER_REAL,&oldtmv,NULL); 46 } 47 48 //装载模块 49 static void mod_load(void) 50 { 51 struct sigaction act ; 52 struct itimerval tmv; 53 54 act.sa_handler = handler; 55 act.sa_flags = 0; 56 sigemptyset(&act.sa_mask); 57 sigaction(SIGALRM,&act,&oldact); 58 59 tmv.it_interval.tv_sec = 1; 60 tmv.it_interval.tv_usec = 0; 61 tmv.it_value.tv_sec = 1; 62 tmv.it_value.tv_usec = 0; 63 setitimer(ITIMER_REAL,&tmv,&oldtmv); 64 65 atexit(mod_unload);//钩子函数,进程结束运行 66 } 67 //获得可用的指针数组索引 68 static int get_pos(void) 69 { 70 for (int i = 0; i < MAX_ALARM; i++) { 71 if (jobs[i] == NULL) 72 return i; 73 } 74 return -1; 75 } 76 77 static int alarm_init(int s,anyfun_t fun,void *arg) 78 { 79 alarm_t *p =NULL; 80 int pos = get_pos(); 81 if(pos <0) 82 return -2; 83 84 //装载模块, 85 mod_load(); 86 87 p = malloc(sizeof(*p)); 88 if(p ==NULL) 89 return -1; 90 91 p->sec = s; 92 p->anyfun = fun; 93 p->argp = arg; 94 jobs[pos] = p; 95 return pos; 96 } 97 98 int anytimer_alarm(sec_t sec,anyfun_t anyfun,void *arg) 99 { 100 int it ; 101 it = alarm_init(sec,anyfun,arg); 102 if(it==-1) 103 return -ENOMEM; 104 else if(it == -2) 105 return -ENOBUFS; 106 107 return it; 108 }