| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1438 人关注过本帖
标题:不能完成功能 求助: ubuntu 18.04 gcc 编译器 使用信号机制完成功能:平时一 ...
只看楼主 加入收藏
Jessica_Rong
Rank: 1
来 自:河北唐山
等 级:新手上路
帖 子:25
专家分:0
注 册:2017-5-12
结帖率:83.33%
收藏
 问题点数:0 回复次数:0 
不能完成功能 求助: 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);
}

图片附件: 游客没有浏览图片的权限,请 登录注册


搜索更多相关主题的帖子: 信号 任务 int void return 
2018-08-30 11:43
快速回复:不能完成功能 求助: ubuntu 18.04 gcc 编译器 使用信号机制完成功能: ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023389 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved