anytime_alarm 任意数量闹钟设定

时间:2022-09-13 21:28:39
#include <stdio.h>
#include <stdlib.h>                    //malloc
//#include <unistd.h>                    //alarm
#include <sys/time.h>                //getitimer
#include "anytimer_alarm.h"
#include <signal.h>                    //sigaction
#include <string.h>                    //strlen

static int init_mod;                //闹钟系统初始标志位
struct sigaction oldact;

//闹钟系统关闭
static void __arr_destroy(void)
{
    sigaction(SIGALRM, &oldact, NULL);
    struct itimerval oldtime;
    oldtime.it_interval.tv_sec = 0;
    oldtime.it_interval.tv_usec = 0;
    oldtime.it_value.tv_sec = 0;
    oldtime.it_value.tv_usec = 0;
    setitimer(ITIMER_REAL, &oldtime, NULL);
    init_mod == 0;
}

//无定时判断
static void __ifarr_NULL(void)
{
    int i;
    for(i = 0; i < 1024 && alarm_arr[i] == NULL; i++);
    if(i == 1024)    {
        __arr_destroy();
    }
}

//中断
static void alarm_handler(int s)
{
    int i;
    for(i = 0; i < 1024; i++)    {
        if(alarm_arr[i] != NULL)    {
            alarm_arr[i]->token--;
            if(alarm_arr[i]->token <= 0)    {
                alarm_arr[i]->anytm(alarm_arr[i]->str);
                free(alarm_arr[i]);
                alarm_arr[i] = NULL;
            }
        }
    }
    __ifarr_NULL();
}

//闹钟系统初始化
static void __alarm_init(void)
{
    struct itimerval newtime;            //时间设定
    newtime.it_interval.tv_sec = 1;
    newtime.it_interval.tv_usec = 0;
    newtime.it_value.tv_sec = 1;
    newtime.it_value.tv_usec = 0;

    struct sigaction act;                //中断设定
    act.sa_handler = alarm_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    setitimer(ITIMER_REAL, &newtime, NULL);
    sigaction(SIGALRM, &act, &oldact);
    init_mod = 1;                        //已初始化
}

//设置闹钟
int anytimer_alarm(int n, anytm_t anytm, const void *p)
{
    if(0 == init_mod)                    //初始化判定
        __alarm_init();
    
    int i;
    alarm_st *anyalarm = NULL;
    
    for(i = 0; i < 1024; i++)    {        //查找空位
        if(alarm_arr[i] == NULL)
            break;
    }
    if(i >= 1024)
        return -1;

    anyalarm = malloc(sizeof(alarm_st) + strlen(p));
    if(NULL == anyalarm)    {
        return -1;
    }
    anyalarm->token = n;
    anyalarm->anytm = anytm;
    strcpy(anyalarm->str,(char *)p);
    alarm_arr[i] = anyalarm;
    return i;
}

//定时关闭
void anytimer_close(int n)
{
    if(alarm_arr[n] != NULL)    {        //清除相应闹钟(未考虑原子
        free(alarm_arr[n]);
        alarm_arr[n] = NULL;
    }
    __ifarr_NULL();
}

//全定时关闭
void anytimer_destroy(void)
{
    __arr_destroy();
    for(int i = 0; i < 1024; i++)    {
        if(alarm_arr[i] != NULL)    {
            free(alarm_arr[i]);
            alarm_arr[i] = NULL;
        }
    }
}
#ifndef __ANYTM_ALARM_H
#define __ANYTM_ALARM_H

#define BUFSIZE 1024
typedef void (*anytm_t) (void *s);


typedef struct    {
    int token;
    anytm_t anytm;
    char str[1];
}alarm_st;

static alarm_st *alarm_arr[BUFSIZE];
//设置定时可重复
int anytimer_alarm(int n, anytm_t anytm, const void *p);
//定时关闭
void anytimer_close(int n);
//全定时关闭
void anytimer_destroy(void);

#endif

相应main函数测试

#include <stdio.h>
#include "anytimer_alarm.h"
#include <unistd.h>


static void any1(void *s)
{
    printf("%s", (char *)s);
    fflush(NULL);
}

int main(void)
{
    int i = 0;
    int td;
    anytimer_alarm(2, any1, "hello2");            //2s1次打印
    anytimer_alarm(4, any1, "hello4");
    td = anytimer_alarm(6, any1, "hello6");
    anytimer_alarm(8, any1, "hello8");
    anytimer_alarm(10, any1, "hello10");
    anytimer_alarm(12, any1, "hello12");

    while(1)    {
        write(1, "*", 1);
        sleep(1);
        i++;
        if(i == 5)                                //第三次关闭
            anytimer_close(td);
        if(i == 9)                                //第四次以后全关闭
            anytimer_destroy();

    }

    return 0;
}

 

测试结果

[uplooking@homework]$ ./a.out 
**hello2**hello4****hello8**********^C