时钟alarm

#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

 

posted @ 2019-03-23 22:33  好好学习me  阅读(293)  评论(0编辑  收藏  举报