利用信號知識褪子,實現(xiàn)多次任意時間調(diào)用函數(shù)
my_alarm.h文件
#ifndef __MY_ALARM_H
#define __MY_ALARM_H
//最多創(chuàng)建1024個任務
#define MAX 1024
//函數(shù)定義
typedef void alarm_func_t(void*);
//添加任務排嫌,成功返回任務ID,失敗返回-1
int anytimer_alarm(int sec, alarm_func_t *func, void *ch);
//取消任務 成功返回0,失敗返回-1;
int anytimer_destory(int id);
#endif
my_alarm.c文件
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include "my_alarm.h"
static void mouder_load(void); //模塊掛載贸营,設置時間贾漏,信號等
static void handler(int s); //信號行為
static void mouder_unload(void); //模塊卸載,恢復時間具伍,信號
static int get_pos(void); //找空閑位置
//定義任務結(jié)構(gòu)體
struct func_st
{
int sec; //秒數(shù)
alarm_func_t *func; //用戶自定義函數(shù)
void *ch; //函數(shù)參數(shù)
};
static struct func_st *line[MAX]; //定義1024長度的數(shù)組存儲結(jié)構(gòu)體地址
static int inited = 0; //設置計時器翅雏,只有當inited為0的時候才調(diào)用模塊掛載函數(shù)
struct sigaction oldact; //舊的信號行為
struct itimerval olditv; //舊的時間鬧鐘
//添加任務,成功返回任務ID人芽,失敗返回-1
int anytimer_alarm(int sec, alarm_func_t *func, void *ch)
{
struct func_st *new;
int pos;
if(inited == 0)
{
mouder_load();
inited = 1;
}
//找空位
pos = get_pos();
if(pos < 0)
return -1;
new=malloc(sizeof(*new));
if(new == NULL)
return -1;
new -> sec = sec;
new -> func = func;
new -> ch = ch;
line[pos] = new;
return pos;
}
//取消任務 成功返回0望几,失敗返回-1;
int anytimer_destory(int id)
{
free(line[id]);
line[id] = NULL;
}
static void mouder_load(void)
{
struct sigaction act;
struct itimerval itv;
act.sa_handler = handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGALRM, &act, &oldact);
itv.it_interval.tv_sec = 1;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, &olditv);
atexit(mouder_unload); //鉤子函數(shù)
}
static void handler(int s)
{
int i;
for(i=0; i<MAX; i++)
{
if (line[i] != NULL) //找不為空的數(shù)組
{
if(line[i] -> sec != 0) //當結(jié)構(gòu)體的時間不等于0時,時間減少1
line[i] -> sec -= 1;
else //時間為0執(zhí)行用戶自定義函數(shù)萤厅,并銷毀該任務橄抹,由于對外提供銷毀函數(shù),所以可以由用戶調(diào)用銷毀惕味,類似父進程為子進程收尸函數(shù)wait()楼誓;
{
line[i] -> func(line[i]->ch);
anytimer_destory(i);
}
}
}
}
static int get_pos(void)
{
for(int i=0; i<MAX; i++)
{
if(line[i] == NULL)
return i;
}
return -1;
}
static void mouder_unload(void)
{
sigaction(SIGALRM, &oldact, NULL);
setitimer(ITIMER_REAL, &olditv, NULL);
}
調(diào)試文件alrm_hw.c
#include <stdio.h>
#include <unistd.h>
#include "my_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;
}
makefile文件
SRC = alrm_hw.o my_alarm.o
OBJ = myalarm
$(OBJ):$(SRC)
gcc -o $@ $^
clean:
rm *.o $(OBJ)
運行結(jié)果
程序運行結(jié)果