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,"\n",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\n",i);
        //文件全缓冲模式,要加刷新
        syslog(LOG_DEBUG , "%d is printed ",i);
        fflush(fp);
        sleep(1);
    }
    exit(0);
}^_
View Code

 

posted @ 2016-03-28 10:19  muzihuan  阅读(500)  评论(0编辑  收藏  举报