简单实现anytimer

实现一个最大1024个不同定时器,定时时间到执行相应的函数。

头文件anytimer.h

#ifndef __ANYTIMER_H__
#define __ANYTIMER_H__

#define MAX_TIMER 1024
typedef void (*func)(void *);

int add_anytimer(int time,func curFun,char *str); //添加定时器
int cancel_anytimer(int timer);        //取消定时器
int wait_anytimer(int timer);         //销毁定时器

#endif

库文件anytimer.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include "anytimer.h"

#define ARGSLENTH 32
enum timerFlag      //定义定时器状态
{
  normal,
  running,
  over
};

typedef struct anytimer_st  //定时器结构体
{
  int time;        //定时时间
  func funPtr;      //函数指针
  char string[ARGSLENTH];  //函数参数
  enum timerFlag flag;    //定时器状态
}anytimer;

static anytimer *timer_st[MAX_TIMER];  //定时器指针数组

static int find_pos(void)    //查找定时器指针数组空闲下标
{
  int i;
  for(i=0;i<MAX_TIMER;i++)
  {
    if(timer_st[i] == NULL)
    return i;
  }
  return -1;
}

static int boot =0;
typedef void (*sighandler_t)(int);
sighandler_t sig_save;

static void alrm_handler(int s)  //定时器处理函数
{
  int i;

  for(i=0;i<MAX_TIMER;i++)  //遍历数组查看注册定时器并更新剩余时间,时间到执行相应函数并更新定时器状态
  {
    if(timer_st[i]!=NULL && timer_st[i]->flag == normal)
    {
      timer_st[i]->time--;
      if(timer_st[i]->time==0)
      {
        timer_st[i]->funPtr(timer_st[i]->string); //调用函数指针传递参数并执行相应函数
        timer_st[i]->flag = over;  //更新定时器状态
      }
    }
  }
}

static void module_load(void)  //首次创建定时器加载
{
  struct itimerval curtimer;

  sig_save = signal(SIGALRM,alrm_handler);  //注册信号处理函数
  
  curtimer.it_interval.tv_sec =1;    //创建定时器
  curtimer.it_interval.tv_usec = 0;
  curtimer.it_value.tv_sec =1;
  curtimer.it_value.tv_usec =0;
  setitimer(ITIMER_REAL,&curtimer,NULL);  //初始化定时器(循环定时)
}

static void module_unload(void)  //异常退出时执行
{
  int i;
  struct itimerval curtimer;

  signal(SIGALRM,sig_save);  //恢复信号以前的动作

  curtimer.it_interval.tv_sec =0;
  curtimer.it_interval.tv_usec = 0;
  curtimer.it_value.tv_sec =0;
  curtimer.it_value.tv_usec =0;
  setitimer(ITIMER_REAL,&curtimer,NULL);  //关掉定时器

  for(i=0;i<MAX_TIMER;i++)  //循环释放申请的内存空间
  {
    if(timer_st[i]!=NULL && timer_st[i]->flag != running)
      free(timer_st[i]);
  }
}

int add_anytimer(int time,func curFun,char *str)  //添加定时器
{
  anytimer *me;
  int pos;

  if(boot ==0)  //首次执行加载定时模块
  {
    boot =1;
    module_load();
  }
  atexit(module_unload);  //钩子函数异常退出时执行

  pos = find_pos();  //查找空闲下标
  if(pos <0)
    return -1;

  if(time==0 || curFun ==NULL || str == NULL)  //参数判断
    return -2;

  me = malloc(sizeof(anytimer));  //申请内存
  if(me ==NULL)
    return -3;

  me->time = time;  //初始化timer结构体
  me->funPtr = curFun;
  strncpy(me->string,str,ARGSLENTH);
  me->flag = normal;

  timer_st[pos] = me;
  return pos;
}

static int pos_isTrue(int pos) //通过下标判断timer是否存在
{
  if(timer_st[pos] !=NULL)
    return 0;
  return -1;
}

int cancel_anytimer(int timer)  //取消timer动作
{
  int ret;

  ret = pos_isTrue(timer);  //判断timer是否存在
  if(ret <0)
    return -1;

  if(timer_st[timer]->flag == running || timer_st[timer]->flag == over)  //判断timer是否正在执行或已经执行
    return -2;

  timer_st[timer]->flag = over;  //更改timer状态
  return 0;
}

int wait_anytimer(int timer)  //回收timer
{
  int ret;

  ret = pos_isTrue(timer);  //判断timer是否存在
  if(ret <0)
    return -1;

  if(timer_st[timer]->flag == running)  //判断timer是否正在执行
    return -2;

  free(timer_st[timer]);  //释放timer空间
  timer_st[timer] = NULL;  

  return 0;
}

主程序main.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "anytimer.h"

static void fun1(void *str)
{
  char *ptr = str;
  printf("%s\n",ptr);
}

int main()
{
  int t1,t2,t3;

  t1 = add_anytimer(5,fun1,"aaa");
  t2 = add_anytimer(2,fun1,"bbb");
  t3 = add_anytimer(10,fun1,"ccc");

  while(1)
    pause();  //等待事件

  // wait_anytimer(t1);
  // wait_anytimer(t2);
  // wait_anytimer(t3);
  exit(0);
}

 

编译文件Makefile

anytimer:anytimer.o main.o
  $(CC) $^ -o $@

clean:
  $(RM) *.o anytimer

 

posted @ 2022-07-19 09:49  *^VV^*  阅读(53)  评论(0编辑  收藏  举报