不能完成功能 求助: ubuntu 18.04 gcc 编译器 使用信号机制完成功能:平时一秒打印一个".",一旦接收到信号就去响应信号,
使用信号机制完成功能:平时一秒打印一个".", 一旦接收到信号就去响应信号,信号每一秒发送一次,
有定时机制,当定下的时间减到0的时候,执行
有两个函数可以实现创建任务,
① .非周期性任务 at_addjob 传入参数:定时为sec秒,你想完成的任务函数jobp,往任务函数jobp里传的参数arg
② .周期性任务 at_addjob_repeat 传入参数:同上 但结构体中的rep_sec也会设置为sec的值
---------------------anytimer.c---------------------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#include "anytimer2.h"
//运行,取消,结束,暂停
#define RUNNING 2001
#define CANCEL 2002
#define OVER 2003
#define STOP 2004
#define LOG (printf("%s (%d)\n",__FUNCTION__,__LINE__))
struct anytimer_st
{
int seco;
at_jobfunc_t *func;
void *argu;
int status;
int rep_sec;
int posi;
};
static struct anytimer_st *myjob[JOB_MAX];
static struct sigaction sa;
static struct sigaction oldsa;
static struct itimerval itv;
static struct itimerval olditv;
static int inited = 1;
//functions
static void alrm_handler(int s,siginfo_t *infop,void *unused);
void module_load();
void module_unload();
static int get_job_pos();
void at_destroy(struct anytimer_st *ptr);
int at_addjob(int sec,at_jobfunc_t *jobp,void *arg);
int at_addjob_repeat(int sec,at_jobfunc_t *jobp,void *arg);
int at_waitjob(int id);//收尸
int at_canceljob(int id);//取消任务
int at_resumejob(int id);//重启
static void alrm_handler(int s,siginfo_t *infop,void *unused)
{
int i;
if(infop->si_code != SI_KERNEL)//查看信号来源
return ;
setitimer(ITIMER_REAL,&itv,&olditv);
LOG;
for(i = 0 ; i < JOB_MAX; i++)
{
if(i==0)
printf("循环开始!\n");
if(myjob[i] != NULL)
{
if(myjob[i]->status = RUNNING)
{
LOG;
if(myjob[i]->seco > 0)
{
(myjob[i]->seco)--;
}
else if(myjob[i]->seco == 0)
{
LOG;
myjob[i]->func(myjob[i]->argu);//调用函数
LOG;
if(myjob[i]->rep_sec)
myjob[i]->seco = myjob[i]->rep_sec;
//说明此任务为周期性任务
else
myjob[i]->status = 111;
}
}
}
}
}
void module_load()
{
//signal
sa.sa_sigaction = alrm_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;//特殊要求
if(sigaction(SIGALRM,&sa,&oldsa) < 0)//保留SIGALRM原有的行为
{
perror("sigaction()");
exit(1);
}
//alarm(1)
//在setitimer方法调用成功后,
//延时1秒便触发一次SIGALRM信号,
//以后每隔1秒触发一次SIGALRM信号。
//interva->时间间隔
//value-> 延时时长
itv.it_interval.tv_sec = 1;
itv.it_interval.tv_usec = 0;
itv.it_interval.tv_sec = 1;
itv.it_interval.tv_usec = 0;
if(setitimer(ITIMER_REAL,&itv,&olditv) < 0)
{
perror("setitimer()");
exit(1);
}
atexit(module_unload);
}
void module_unload(void)
{
sa.sa_sigaction = alrm_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;//特殊要求
if(sigaction(SIGALRM,&sa,&oldsa) < 0)
{
perror("sigaction()");
exit(1);
}
itv.it_interval.tv_sec = 1;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = 1;
itv.it_value.tv_use if(setitimer(ITIMER_REAL,&itv,NULL) < 0)
{
perror("setitimer()");
exit(1);
}
atexit(module_unload);
}
int at_addjob(int sec,at_jobfunc_t *jobp,void *arg)
{
struct anytimer_st *me;
int pos = 0;
if(sec < 0 || !jobp)
{
printf("传入参数错误!!\n");
return -EINVAL;//参数非法
}
me = malloc(sizeof(me));
if(me == NULL)
{
return -ENOMEM;//内存分配失败
printf("malloc() error!\n");
}
pos = get_job_pos();
if(pos < 0)
{
free(me);
printf("get_job_pos() eror!\n");
exit(1);
}
me->seco = sec-1;
me->func = jobp;
me->argu = arg;
me->status = RUNNING;
me->rep_sec = 0;
myjob[pos] = me;
me->posi = pos;
if(inited)
{
module_load();
inited = 0;
}
return pos;
}
int at_addjob_repeat(int sec,at_jobfunc_t *jobp,void *arg)
{
struct anytimer_st *me;
int pos = 0;
if(inited)
{
module_load();
inited = 0;
}
if(sec < 0 || !jobp)
{
printf("传入参数错误!!\n");
return -EINVAL;//参数非法
}
me = malloc(sizeof(me));
if(me == NULL)
return -ENOMEM;//内存分配失败
me->seco = sec;
me->func = jobp;
me->argu = arg;
me->status = RUNNING;
me->rep_sec = sec;//仅有此处与at_addjob不同
pos = get_job_pos();
if(pos < 0)
{
free(me);
return -1;
}
myjob[pos] = me;
me->posi = pos;
return pos;
}
static int get_job_pos()
{
int i;
for(i = 0 ; i < JOB_MAX; i++)
return i;
return -ENOSPC;//数组已满
}
void at_destroy(struct anytimer_st *ptr)
{
struct anytimer_st *me = ptr;
myjob[me->posi] = NULL;
free(ptr);
}
//被取消的任务,和已经结束的任务都将被收尸
int at_waitjob(int id)//收尸
{
if(id < 0 || id >= JOB_MAX || myjob[id] == NULL)
return -EINVAL;//参数非法
if(myjob[id]->rep_sec > 0)
return -EBUSY;//此任务为周期性任务
if(myjob[id]->status == CANCEL || myjob[id]->status == OVER)
at_destroy(myjob[id]);
return 0;
}
int at_canceljob(int id)//取消任务
{
if(id < 0 || id >= JOB_MAX || myjob[id] == NULL)
return -EINVAL;//参数非法
if(myjob[id]->rep_sec > 0 || myjob[id]->seco == 0)
return -EBUSY;//此任务为周期性任务/该任务已结束
if(myjob[id]->status == CANCEL)
return -ECANCELED;//该任务早已被取消
myjob[id]->status = CANCEL;
return 0;
}
int at_stopjob(int id)//暂停任务
{
if(id < 0 || id >= JOB_MAX || myjob[id] == NULL)
return -EINVAL;//参数非法
if(myjob[id]->seco == 0)
return -EBUSY;//任务已结束
if(myjob[id]->status == STOP)
return -ECANCELED;//该任务早已被暂停
myjob[id]->status = STOP;
return 0;
}
//只能重启被暂停的任务
int at_resumejob(int id)//重启
{
if(id < 0 || id >= JOB_MAX || myjob[id] == NULL)
return -EINVAL;//参数非法
if(myjob[id]->rep_sec > 0 || myjob[id]->status == RUNNING)
return -EBUSY;//此任务为周期性任务/正在运行的任务
if(myjob[id]->status == CANCEL)
return -ECANCELED;//该任务早已被取消
myjob[id]->status = CANCEL;
return 0;
}
------------------------------------------anytimer2.h-------------------------------------
#ifndef ANYTIMER_H__
#define ANYTIMER_H__
#define JOB_MAX 1024
typedef void at_jobfunc_t(void *);
int at_addjob(int sec,at_jobfunc_t *jobp,void *arg);
/*
return >= 0 成功,返回任务ID
== -EINVAL 失败,参数非法
== -ENOMEM 失败,内存分配失败
== -ENOSPC 失败,任务数组已满
*/
int at_addjob_repeat(int sec,at_jobfunc_t *jobp,void *arg);
/*
同上
*/
int at_canceljob(int id);
/*
return == 0 成功,指定任务已取消
== -EINVAL 失败,参数非法
== -EBUSY 失败,指定任务已执行结束
== -ECANCELED 失败,指定任务早已被取消
*/
int at_stopjob(int id);//暂停
int at_resumejob(int id);//重启
int at_waitjob(int id);//收尸
/*
return == 0 成功,指定任务已释放
== -EINVAL 失败,参数非法
== -EBUSY 失败,指定任务为周期性任务
*/
#endif
-------------------------------------------------main.c-------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "anytimer2.h"
void f1(void *p)
{
char* ch = p;
printf("f1():%s\n",ch);
}
void f2(void *p)
{
char* ch = p;
printf("f2():%s\n",ch);
}
int main()
{//Begin!End!..bbb...aaa..ccc...............
int job1;
puts("Begin!");
job1 = at_addjob(5,f1,"aaa");
if(job1 < 0)
{
printf("at_addjob():\n");
exit(1);
}
printf("job1 = %d\n",job1);
// at_addjob_repeat(2,f2,"bbb");
at_addjob(7,f1,"ccc");
puts("End!");
// at_waitjob(job1);
while(1)
{
write(1,".",1);
sleep(1);
}
exit(0);
}