sigaction() 使用

    xiaoxiao2025-09-17  29

    /**   * @file demo7.c  * @Synopsis    *  * int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact)  * @param signum  * @param struct sigaction * oldact  -> NULL  * @param const struct sigaction *act  *  * 注:阻塞的意思是延迟相应信号  * sigaction,是为替代signal 来设计的较稳定的信号处理。  * typedef void (*sighandler_t)(int);  * sighandler_t signal(int signum,sighandler_t handler);  * 不能完成的任务:{  *  1:不知道信号产生的原因;  *  2:处理信号中不能阻塞其他信号  * }  * 而signaction , 则可以设置比较多的信号消息。  *                  尤其是在信号处理函数过程中接受信号,进行何种处理。  *  * sigaction 函数用于改变进程接收到特定信号后的行为。  * 该函数的第一个参数为信号的值,可以为除SIGKILL 及SIGSTOP外的任何一个特定有效的信号(为  *      这两个信号定义自己的处理函数,将导致信号安装错误)。  * 第二个参数是指向结构sigaction 的一个实例的指针,在结构体sigaction的实例中,指定了对  *      特定信号的处理,可以为空,进程会以缺省方式对信号处理;  * 第三个参数oldact 指向的对象用来保存原来对应信号的处理,可指定oldact 为NULL.  * 如果把第二,第三个参数都设为NULL,那么该函数可用于检查信号的有效性。  * 第二个参数最为重要,其中包含了对指定信号的处理,信号所传递的信息,信号处理函数执行过程  * 中应屏蔽掉哪些函数等等。  *  * struct sigaction{  *  void (*sa_handler)(int);// like signal  *  void (*sa_sigaction)(int,siginfo_t *,void *);//   *  sigset_t sa_mask;  *  int sa_flags;  *  void (*sa_restorer)(void);  * }  * 其中sa_restorer,己过时POSIX不支持它,不再使用它  *  * SIGKILL and SIGSTOP 这两个信号是不能屏蔽的。  * 如果 sa_flags -> SA_SIGINFO....则会调用 sigaction  * sa_mask 指出来一组信号,可以被阻塞。。  *  * sa_flags{  *  SA_NODEFER  *  SA_RESETHAND  *  SA_RESTART  *  SA_SIGINFO  * }  * sa_mask{  *  *  // 信号设置,信号集合,一堆信号。kill -l   *  // 小于 34的 叫普通信号  *  // 大于等于34 叫实施信号  *  // sigset_t 看成一个整数  *  sigset_t{  *      sigismember // 判断某一个信号是否在里面  *      setfillset/sigdelset // 把所有位置位1,/把里面的某一个位删除设置0  *      sigemptyset/sigaddset // 集合里面所有位清0 /把某一个清0  *  }  *  sigprocmask  * }  *  * sigset_t s1;  *       0 0 0 0 0 0 0 0 0  * 集合:0 1 2 3 4 5 6 7 8  *  * s1 = 2;  * 怎么样得到一个信号集合。。  * 我们有一糸列的函数  * 信号集合大于16  * fill 往后面减。  * 小于16个信号  * 清空往里面加  * 不同糸统作法不一样。。  *  * signal 间接调用 sigaction  * @author MrClimb  * @version 1.1.0  * @date 2012-05-20  */ #include <stdio.h> #include <unistd.h> #include <signal.h> #define INPUTLEN 100 void inthandler();

    int main(int argc, char **argv) {     struct sigaction newhandler;     sigset_t blocked;// 信号集合     char x[INPUTLEN];

        newhandler.sa_handler = inthandler;     // 不加SA_NODEFER 只处理一次性号。     // 而加上则每次信号都将处理。     // newhandler.sa_flags = SA_RESTART;// ^C 只接收一次性号。连续按不接收; 设置 0 也可以;

        // 3)当上面去掉了SA_NODEFER标志位。程序在执行信号处理函数过程中,^C信号将会被阻止,     // 但是执行信号处理函数期发送的^C信号将会被阻塞,知道信号处理函数执行完成,才有机会处理     // 信号函数执行期间产生的^C,但是在信号函数执行产生的多次^C,最后只产生^C     // 而下面设置了SA_NODEFER,^C信号将不会被阻塞。所以能够并行执行下次的信号处理函数。     // newhandler.sa_flags = SA_RESTART | SA_NODEFER;// ^C 连续按每一次都接收(程序都不会结束)          // 1)第一次产生^C 信号时候,该信号被自己设定的信号处理函数时行了处理。在处理过程中,     // 由于这里设定了SA_RESETHAND标志位,又将该信号的处理函数设置为默认的信号处理     // 函数(糸统默认的处理方式为IGN),所以在第二次发送^C信号的时候,是由默认的信号     // 算是函数处理的,导致程序结束,     // 2) 当根据上面没有SA_RESETHAND标志位,导致程序中所有的^C信号均是由我们自己的信号     // 处理函数来进行处理,所以我们发关多少次^C信号程序都不会退出     newhandler.sa_flags = SA_RESTART | SA_NODEFER | SA_RESETHAND;//^C 按一次执行,按第二次^C 则停止该进程

        sigemptyset(&blocked);

        sigaddset(&blocked,SIGQUIT);// 往集合里加一个SIGQUIT 信号(^\)     sigaddset(&blocked,SIGTSTP);// 添加 终止信号 ^Z     /**     * sa_mask 在信号处理函数运行时 屏蔽所有的信号除了SIGSTOP & SIGKILL 两个信号外,     * 当然上面blocked 信号被置空了,重新设置了上面两个信号,当接收到上面两个信号,则     * 执行屏蔽操作,退出程序。     */     newhandler.sa_mask = blocked;// 将blocked 传给 sa_mask 时,它才屏蔽后一个信号    

        if(sigaction(SIGINT,&newhandler,NULL)== -1)     {         perror("sigaction");     }else     {         while(1)         {             fgets(x,INPUTLEN,stdin);             printf("input: %s",x);         }     }     return 0; } void inthandler(int s) {     printf("Called with signal %d\n",s);     sleep(s*3);     printf("done handling signal %d\n",s); }

    转载请注明原文地址: https://ju.6miu.com/read-1302746.html
    最新回复(0)