zoukankan      html  css  js  c++  java
  • UEA20181224 郭恩赐 作业2019 3 22

    实现功能

        信号设定闹钟,可以一次设定多个闹钟,谁的时间短谁先触发,并执行相应的操作

    运行结果

    gec@tbf$ ./a.out
    **world*hello**apue********

    main.c

    #include <stdio.h>
    #include "anytimeralarm.h"
    #include<unistd.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;
    }

    anytimeralarm.h

    #ifndef __ANYTIMERALARM_H
    #define __ANYTIMERALARM_H
    
    #define MAX_ALARM 1024 //最多可同时设置1024个闹钟
    
    //typedef 秒是无符号整形的
    typedef unsigned int  sec_t;
    
    //定义函数指针类型 anyfun_t
    typedef void (*anyfun_t)(void *); 
    
    /*
        函数功能:设定倒计时时间执行相应程序,多次设定时间短的先执行
        参数
            1,sec 是unsigned int sec设定闹钟倒计时的秒数;
            2,anyfun是函数指针,参数任意类型指针,无返回值。
            3,arg 是传给anyfun函数的参数。
        成功返回值 0 ;失败返回 -1
     */
    
    int anytimer_alarm(sec_t sec,void (*anyfun)(void *),void *arg);
    
    #endif

    anytimeralarm.c

      1 #include<stdlib.h>
      2 #include<sys/time.h>
      3 #include<signal.h>
      4 #include<errno.h>
      5 #include"anytimeralarm.h"
      6 
      7 //定义每个闹钟的结构
      8 typedef struct {
      9     sec_t sec;
     10    //   void (*anyfun)(void*);
     11     anyfun_t anyfun;
     12     void *argp;
     13 }alarm_t;
     14 
     15 //定义一个函数指针最多存放1024个闹钟
     16 static alarm_t *jobs[MAX_ALARM];
     17 
     18 //定义设置信号和闹钟之前的状态
     19 struct sigaction oldact;
     20 struct itimerval oldtmv;
     21 
     22 //信号响应处理函数
     23 static void handler(int s)
     24 {
     25     int i;
     26     anyfun_t fun;
     27     for(i = 0;i<MAX_ALARM;i++){
     28         if(jobs[i]){
     29             jobs[i]->sec -= 1 ; 
     30             if(jobs[i]->sec == 0){ 
     31                 fun = jobs[i]->anyfun;
     32                 fun(jobs[i]->argp);
     33     
     34                 free(jobs[i]);
     35                 jobs[i] = NULL;
     36             }
     37         }
     38     }   
     39 }
     40 
     41 //卸载模块
     42 static void mod_unload(void)
     43 {
     44     sigaction(SIGALRM,&oldact,NULL);
     45     setitimer(ITIMER_REAL,&oldtmv,NULL);
     46 }
     47 
     48 //装载模块
     49 static void mod_load(void)
     50 {
     51     struct sigaction act ;
     52     struct itimerval tmv;
     53 
     54     act.sa_handler  = handler;
     55     act.sa_flags = 0;
     56     sigemptyset(&act.sa_mask);
     57     sigaction(SIGALRM,&act,&oldact);
     58 
     59     tmv.it_interval.tv_sec = 1;
     60     tmv.it_interval.tv_usec = 0;
     61     tmv.it_value.tv_sec = 1;
     62     tmv.it_value.tv_usec = 0;
     63     setitimer(ITIMER_REAL,&tmv,&oldtmv);
     64 
     65     atexit(mod_unload);//钩子函数,进程结束运行
     66 }
     67 //获得可用的指针数组索引
     68 static int get_pos(void)
     69 {
     70     for (int i = 0; i < MAX_ALARM; i++) {
     71         if (jobs[i] == NULL)
     72             return i;
     73     }
     74     return -1;
     75 }
     76 
     77 static int alarm_init(int s,anyfun_t fun,void *arg)
     78 {
     79     alarm_t *p =NULL;
     80     int pos = get_pos();
     81     if(pos <0)
     82         return -2;
     83 
     84     //装载模块,
     85     mod_load();
     86 
     87     p = malloc(sizeof(*p));
     88     if(p ==NULL)
     89         return -1;
     90 
     91     p->sec = s;
     92     p->anyfun = fun;
     93     p->argp = arg;
     94     jobs[pos] = p;
     95     return pos;
     96 }
     97 
     98  int anytimer_alarm(sec_t sec,anyfun_t anyfun,void *arg)
     99 {
    100     int it ;
    101     it = alarm_init(sec,anyfun,arg);
    102     if(it==-1)
    103         return -ENOMEM;
    104     else if(it == -2)
    105         return -ENOBUFS;
    106 
    107     return it;
    108 }
  • 相关阅读:
    缓慢画点功能实现的两个方法
    c++编译器对新建字符型数组内部数据的初始化
    在win7下用net命令无法实现对用户的创建(未完成)
    关于sleep函数的一些问题和资料
    C++ 临时笔记
    boost::progress_timer 与 boost::progress_display
    《C++ Primer》 Part IV(ObjectOriented and Generic Programming)
    Linux下常用软件
    《C++STL基础及应用》读书笔记
    boost::asio
  • 原文地址:https://www.cnblogs.com/gec258/p/10583283.html
Copyright © 2011-2022 走看看