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 }
原文地址:https://www.cnblogs.com/gec258/p/10583283.html