• linux高编信号-------信号集


    信号集的函数:

    类型:sigset_t 类型

    #include <signal.h>
    
    /****************************
     *功能:把一个信号集的内容清空
     *参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
     *返回值:成功返回0,失败返回-1
     * ************************/
    int sigemptyset(sigset_t *set);
    
    /****************************
     *功能:把一个信号集的内容填满,包含所有的信号
     *参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
     *返回值:成功返回0,失败返回-1
     * ************************/
    int sigfillset(sigset_t *set);
    
    
    /****************************
     *功能:把一个信号添加到信号集中
     *参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
     *返回值:成功返回0,失败返回-1
     * ************************/
    int sigaddset(sigset_t *set, int signum);
    
    /****************************
     *功能:把一个信号从信号集中删除
     *参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
     *返回值:成功返回0,失败返回-1
     * ************************/
    int sigdelset(sigset_t *set, int signum);
    
    /****************************
     *功能:判断是否是信号是否在指定集合中
     *参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
     *返回值:成功返回0,失败返回-1
     * ************************/
    int sigismember(const sigset_t *set, int signum);
    #include <signal.h>
    /***************信号屏蔽字***********
     *功能:检查和更改阻塞信号
     *参数:how:SIG_BLOCK:阻塞(eg:阻塞住set中的信号成员)
     *      set:信号集所有对象
     *返回值:成功返回0,失败返回-1
     * **********************************/
    int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
    /*****************************************
     *功能:等待一个信号(pause)
     *步骤1:设置新的mask阻塞当前进程
     *步骤2:收到信号,调用该进程设置的信号处理函数
     *步骤3:待信号处理函数返回后,恢复之前的mask
     * **************************************/
    int sigsuspend(const sigset_t *mask);
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    
    void func(int s)
    {
    
        write(1,"!",1);
    }
    
    int main(void)
    {
        int i , j ;
        sigset_t set ,oset ,saveset ;
        //1.设置信号
        signal(SIGINT,func);
        //2.信号集清空
        sigemptyset(&set);
        //3.将信号SIGINT添加到信号集
        sigaddset(&set , SIGINT);
        //4.将信号集中信号从当前的信号掩码中删除,并保存UNBLOCK之前的信号状态
        //  保存模块使用前的状态不被改变
        sigprocmask(SIG_UNBLOCK , &set , &saveset);
        //5.将信号集中的信号加到信号掩码中使用,并保存BLOCK之前的信号状态
        sigprocmask(SIG_BLOCK , &set , &oset);
        //6.打印*****换行
        for(i = 0 ; i < 1000 ; i++)
        {
            for(j = 0 ; j  < 5 ; j++)
            {
                write(1 , "*",1);
                sleep(1);
            }
            write(1,"
    ",1);
            //7.等待一个信号,信号到来驱动程序进行
            sigsuspend(&oset);//原子操作
            #if 0
            sigset_t tmpset ;
            sigprocmask(SIG_SETMASK , &oset ,&tmpset);//解除阻塞
            pause();//等待信号
            sigprocmask(SIG_SETMASK , &tmpset ,&NULL);//恢复阻塞
            #endif
        }
        //8.恢复之前的状态(要有模块概念,不应该更改信号前的状态)与4对应
        sigprocmask(SIG_SETMASK , &saveset , NULL);
        exit(0);
    }
    /************************
     *功能:替代signal函数:检查或者修改指定信号相关处理函数
     *参数:signum:信号num
     *      act:定义新的行为
     *      oldact:保存旧的行为
     * **********************/
    int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
    
    
    struct sigaction {
        void     (*sa_handler)(int);//替换signal
        void     (*sa_sigaction)(int, siginfo_t *, void *);//具有三个参数的信号处理函数
        sigset_t   sa_mask;//需要block住的信号
        int        sa_flags;//特殊要求
        void     (*sa_restorer)(void);
    };

    eg:

    /***********************
     *功能:创建守护进程
     *      添加系统日志
     * ********************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <syslog.h>
    #include <errno.h>
    #include <signal.h>
    
    //守护进程创建后不断向FNAME中写入数字
    #define  FNAME "/tmp/out"
    
    static FILE *fp ;
    static int daemonize(void )
    {
        pid_t pid ;
        int fd ;
        int i ;
        //1.创建进程
        pid = fork();
        if(pid < 0)
            return -1;
        //2.子进程
        if(pid == 0)
        {
            //脱离控制终端 读写形式打开一个设备
            fd = open("/dev/null",O_RDWR);
            if(fd < 0)
                return -1 ;
            //重定向:将fd重定向到0 ,1 ,2
            dup2(fd , 0 );
            dup2(fd , 1 );
            dup2(fd , 2 );
            if(fd > 2)
                close(fd);
    
            //守护进程产生
            setsid();
            //当前的工作路径为根目录,如果是挂载的文件卸载可能回busy
            chdir("/");
            //在程序中不会产生文件的情况下
            umask(0);
            return 0 ;
        }
        else//2.父进程
            exit(0);
    }
    /*当信号处理函数实现过程中
     * 多个信号共用同一个处理函数的时候
     * 在处理一个信号的过程中
     * 需要把其他的信号block住*/
    static void damon_exit(int s )
    {
        fclose(fp);
        closelog();
        exit(0);
    }
    
    
    int main()
    {
        int i ;
        struct sigaction sa ;
        /*sigaction使用*/
        sa.sa_handler = damon_exit ;
        sigemptyset(&sa.sa_mask);
    
        sigaddset(&sa.sa_mask , SIGQUIT);
        sigaddset(&sa.sa_mask , SIGTERM);
        sigaddset(&sa.sa_mask , SIGINT);
        sa.sa_flags = 0 ;
        sigaction(SIGINT,&sa,NULL);
        sigaction(SIGQUIT,&sa,NULL);
        sigaction(SIGTERM,&sa,NULL);
    
    
        /*多个信号用一个信号处理函数:如果有重入的危险*/
        //signal(SIGINT,damon_exit);
        //signal(SIGQUIT,damon_exit);
        //signal(SIGTERM,damon_exit);
    
        //0.建立系统日志
        openlog("mydeamon",LOG_PID,LOG_DAEMON);
    
        //1.创建守护进程
        if(daemonize())
        {
            syslog(LOG_ERR ,"deamonize() failed !");
            exit(1);
        }
        else
        {
            syslog(LOG_INFO,"deamonize() success !");
        }
        //===========守护进程工作==============
        //2.以写的方式打开文件
        fp = fopen(FNAME , "w");
        if(fp == NULL)
        {
            syslog(LOG_ERR,"fopen()%s",strerror(errno));
            exit(1);
        }
        syslog(LOG_INFO ,"%s was opened",FNAME);
        //3.不断写入i的值eg:1 2 3 4 ......
        for(i = 0 ;; i++)
        {
            fprintf(fp,"%d
    ",i);
            //文件全缓冲模式,要加刷新
            syslog(LOG_DEBUG , "%d is printed ",i);
            fflush(fp);
            sleep(1);
        }
        exit(0);
    }^_
    View Code
  • 相关阅读:
    (二)正反向代理
    (一)服务器架构详解
    斐波那契数列
    旋转数组的最小值
    23 入栈 出栈
    重建二叉树
    22 大端序和小端序
    反转单链表
    替换空格
    二维数组中的查找
  • 原文地址:https://www.cnblogs.com/muzihuan/p/5317629.html
Copyright © 2020-2023  润新知