精华内容
下载资源
问答
  • sigaction

    2021-02-22 14:11:31
    信号捕捉 防止进程意外死亡 typedef void(*sighandler_t)(int); sighandler_t signal(int signum,sighander...int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact); signum 捕捉的信号 ac

    信号捕捉

    防止进程意外死亡

    typedef void(*sighandler_t)(int);

    sighandler_t signal(int signum,sighander_t handler);
    signum要捕捉的信号
    handler要执行的捕捉函数指针,函数应该声明void func(int);

    注册捕捉函数
    int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);
    signum 捕捉的信号
    act 传入的动作
    oldact 原动作,恢复现场
    struct sigaction{
    void (*sa_handler)(int); //函数指针
    void (*sa_sigaction)(int,siginfo_t *,void *);
    sigset_t sa_mask; //执行捕捉函数期间,临时屏蔽的信号集
    int sa_flags; //一般为0,SAT_SIGINFO会使用第二个函数指针
    void (*sa_restorer)(void); //无效
    };

    sigaction.c

    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    #include <sys/type.h>
    
    void catch_sig(int num){
        printf("catch %d sig\n",num);
    }
    
    int main(int argc,char * argv[])
    {
        //注册一下捕捉函数
        struct sigaction act;
        act.sa_flags=0;
        act.sa_handler=catch_sig;
        sigempty(&act.sa_mask);
        sigaction(SIGALRM,&act,NULL);
        //setitimer
        struct itimerval myit={{3,0},{5,0}};
        setitimer(ITIMER_REAL,&myit,NULL);
        while(1){
            printf("xxx\n");
            sleep(1);
        }
    
        return 0;
    }
    
    

    sigaction_mask.c

    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    #include <sys/type.h>
    
    void catch_sig(int num){
        printf("begin call,catch %d sig\n",num);
        sleep(5); //模拟捕获函数执行时间较长
        printf("end call,catch %d sig\n",num);
    }
    
    int main(int argc,char * argv[])
    {
        //注册一下捕捉函数
        struct sigaction act;
        act.sa_flags=0;
        act.sa_handler=catch_sig;
        sigempty(&act.sa_mask);
        sigaddset(&act.sa_mask,SIGQULT); //临时屏蔽ctrl+\信号
        sigaction(SIGINT,&act,NULL);
    
        while(1){
            printf("xxx\n");
            sleep(1);
        }
    
        return 0;
    }
    
    展开全文
  • posix sigaction

    2016-08-25 17:58:23
    sigaction

    signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受到了一定的限制。而 POSIX 标准定义的信号处理接口是 sigaction 函数,具有较好的可移植性。

           #include <signal.h>
    
           int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
    
           int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
    
           int sigpending(sigset_t *set);
    
           int sigsuspend(const sigset_t *mask);

    The sigaction system call is used to change the action taken by a process on receipt of a specific signal.
    signum不可以是SIGKILL和SIGSTOP,即用户不可以自定义SIGKILL和SIGSTOP的信号处理函数
    signum specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.
    如果act非空,会为signum安装act中指定的新的信号处理函数,如果oldact非空,signum原来的信号处理函数会被保存到oldact中
    If act is non-null, the new action for signal signum is installed from act. If oldact is non-null, the previous action is saved in oldact.

    The sigaction structure is defined as something like

    
        struct sigaction {
            void (*sa_handler)(int);
            void (*sa_sigaction)(int, siginfo_t *, void *);
            sigset_t sa_mask;
            int sa_flags;
            void (*sa_restorer)(void);
        }

    sa_handler

    成员 sa_handler 是一个函数指针,其含义与 signal 函数中的信号处理函数类似,只接收signum作为其参数
    sa_handler specifies the action to be associated with signum and may be SIG_DFL for the default action, SIG_IGN to ignore this signal, or a pointer to a signal handling function. This function receives the signal number as its only argument.

    SIG_DFL & SIG_IGN

    SIG_DFL:默认信号处理程序
    SIG_IGN:忽略信号的处理程序
    是标准库里定义的无返回值的函数指针,指针值分别是0和1,这两个指针值逻辑上讲是实际程序中不可能出现的函数地址值。

    #define SIG_DFL ((void(*)(int))0)
    #define SIG_IGN ((void(*)(int))1)

    sa_sigaction

    sa_sigaction有三个参数,第一个是signum,第二个是siginfo_t指针
    sa_sigaction also specifies the action to be associated with signum. This function receives the signal number as its first argument, a pointer to a siginfo_t as its second argument and a pointer to a ucontext_t (cast to void *) as its third argument
    注意,在某些系统中sa_handler和sa_sigaction被放在union中,因而不要同时设置sa_handler和sa_sigaction

    sa_mask

    sa_mask 成员用来指定在信号处理函数执行期间需要被屏蔽的信号。特别的,如果signum的sa_flags中没有设置*SA_NODEFERSA_NOMASK ,那么signum会默认被添加到signum的sa_mask中,因而该信号的信号处理函数执行期间,重复收到的该信号会被屏蔽掉*
    sa_mask gives a mask of signals which should be blocked during execution of the signal handler。In addition, the signal which triggered the handler will be blocked, unless the SA_NODEFER or SA_NOMASK flags are used.

    sa_flags

    sa_flags用于指定信号处理的行为,是以下值得按位或
    sa_flags specifies a set of flags which modify the behaviour of the signal handling process. It is formed by the bitwise OR of zero or more of the following:
    SA_RESTART: 使被信号打断的系统调用自动重新发起。
    解释:信号是异步的,它会在程序的任何地方发生。由此程序正常的执行路径被打破,去执行信号处理函数。一般情况下 ,进程正在执行某个系统调用,那么在该系统调用返回前信号是不会被处理的,需要等到系统调用结束后才处理。但慢速系统调用除外,如读写终端、网络、磁盘,以及wait和pause,在这些系统调用的过程中,如果收到了信号,操作系统会马上调用这些信号的信号处理函数来处理这些信号,而这些系 统调用都会返回-1,errno置为EINTR表示这些系统调用被信号中断。为了处理慢速系统调用被信号中断的问题,我们可以采用如下两种方式中的一种:
    1. 判断errno,然后重新发起系统调用重试
    2. 给signum信号的sa_flag设置 SA_RESTART
    下面给出了一个试用SA_RESTART的示例:
    #include <stdio.h>                                                                                 
    #include <stdlib.h>                                                                                
    #include <unistd.h>                                                                                
    #include <stdbool.h>                                                                               
    #include <signal.h>                                                                                
    #include <sys/types.h>                                                                             
    #include <errno.h>                                                                                 
    #include <string.h>
    
    void int_handler (int signum)                                                                      
    {                                                                                                  
        printf ("int handler %d\n",signum);                                                            
        return;                                                                                        
    }                                                                                                  
    
    int main(int argc, char **argv)                                                                    
    {                                                                                                  
        char buf[100];                                                                                 
        ssize_t ret;                                                                                   
        struct sigaction oldact;                                                                       
        struct sigaction act;                                                                          
    
        act.sa_handler = int_handler;                                                                  
        act.sa_flags=0;                                                                                
        act.sa_flags |= SA_RESTART;                                                                    
        sigemptyset(&act.sa_mask);                                                                     
        if (-1 == sigaction(SIGINT,&act,&oldact))                                                      
        {                                                                                              
            printf("sigaction failed!\n");                                                             
            return -1;                                                                                 
        }                                                                                              
    
        bzero(buf,100);                                                                                
    
        ret = read(STDIN_FILENO,buf,10);                                                               
        if (ret == -1)                                                                                 
        {                                                                                              
            printf ("read error %s\n", strerror(errno));                                               
        }                                                                                              
        printf ("read %d bytes, content is %s\n",ret,buf);                                             
        sleep (10);                                                                                    
        return 0;                                                                                      
    }
    SA_NOCLDSTOP
    使父进程在它的子进程stop时不会收到 SIGCHLD 信号。
    If signum is SIGCHLD, do not receive notification when child processes stop (i.e., when child processes receive one of SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU)
    SA_NOMASK or SA_NODEFER
    信号处理期间,不要屏蔽同一个信号
    Do not prevent the signal from being received from within its own signal handler.
    SA_SIGINFO
    如果设置了该标志位,那么收到signum信号的时候,会调用sa_sigaction安装的信号处理函数(三参数版本的信号处理函数),而不会调用sa_handler安装的信号处理函数(一参数版本的信号处理函数)
    The signal handler takes 3 arguments, not one. In this case, sa_sigaction should be set instead of sa_handler

    sa_restorer

    废弃的字段,不要使用。

    siginfo_t结构体

    struct sa_sigaction 中的siginfo_t定义如下:

    siginfo_t {
        int      si_signo;  /* Signal number */
        int      si_errno;  /* An errno value */
        int      si_code;   /* Signal code */
        pid_t    si_pid;    /* Sending process ID */ 
        uid_t    si_uid;    /* Real user ID of sending process */
        int      si_status; /* Exit value or signal */
        clock_t  si_utime;  /* User time consumed */
        clock_t  si_stime;  /* System time consumed */
        sigval_t si_value;  /* Signal value */
        int      si_int;    /* POSIX.1b signal */
        void *   si_ptr;    /* POSIX.1b signal */
        void *   si_addr;   /* Memory location which caused fault */
        int      si_band;   /* Band event */ 
        int      si_fd;     /* File descriptor */ 
    }

    si_signo,si_errno,si_code这三个字段对所有的信号都生效,剩下的字段可能被定义为union,所以对于给定的信号,需要读取对该信号有意义的字段。如kill和SIGCHLD会设置si_pid和si_uid字段,等等。
    si_signo, si_errno and si_code are defined for all signals. The rest of the struct may be a union, so that one should only read the fields that are meaningful for the given signal. kill(2), POSIX.1b signals and SIGCHLD fill in si_pid and si_uid. SIGCHLD also fills in si_status, si_utime and si_stime. si_int and si_ptr are specified by the sender of the POSIX.1b sig nal. SIGILL, SIGFPE, SIGSEGV and SIGBUS fill in si_addr with the address of the fault. SIGPOLL fills in si_band and si_fd.

    si_code显示了这个信号被触发的原因。
    si_code indicates why this signal was sent

    sigprocmask

    int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
    该函数的行为依赖于how参数
    The sigprocmask call is used to change the list of currently blocked signals. The behaviour of the call is dependent on the value of how, as follows.
    SIG_BLOCK,
    SIG_UNBLOCK
    SIG_SETMASK: The set of blocked signals is set to the argument set
    展开全文
  • c语言信号处理sigaction(2011-04-18 23:45:19)标签:c语言信号处理sigactionsighupit分类:c信号安装函数sigaction(int signum,const struct sigaction *act,struct sigaction*oldact)的第二个参数是一个指向...

    c语言信号处理sigaction

    a4c26d1e5885305701be709a3d33442f.png

    (2011-04-18 23:45:19)

    标签:

    c语言

    信号处理

    sigaction

    sighup

    it

    分类:

    c

    信号安装函数sigaction(int signum,const struct sigaction *act,struct sigaction

    *oldact)的第二个参数是一个指向sigaction结构的指针(结构体名称与函数名一样,千万别弄混淆了)。在结构sigaction的实例中,指定了对特定信号的处理,信号所传递的信息,信号处理函数执行过程中应屏蔽掉哪些函数等。当然,此指针也可以为NULL,进程会以默认方式处理信号。以下就简单介绍一下sigaction结构以及一般的用法。

    对于内核头文件而言,struct sigaction

    结构体定义在kernel/include/asm/signal.h,此头文件又被kernel/include/linux/signal.h包含。

    对于用户空间的头文件而言,struct sigaction定义在

    /usr/include/bits/sigaction.h,此头文件又被/usr/include/signal.h包含,所以应用程序中如果用到此结构,只要#include

    即可。注意内核中的定义和应用程序中的定义是不一样的,内核空间的sigaction结构只支持函数类型为

    __sighandler_t的信号处理函数,不能处理信号传递的额外信息。具体定义如下:

    ……

    typedef void (*__sighandler_t)(int);

    ……

    #ifdef __KERNEL__

    struct old_sigaction {

    __sighandler_t sa_handler;

    old_sigset_t sa_mask;

    unsigned long sa_flags;

    void (*sa_restorer)(void);

    };

    struct sigaction {

    __sighandler_t sa_handler;

    unsigned long sa_flags;

    void (*sa_restorer)(void);

    sigset_t sa_mask;

    };

    struct k_sigaction {

    struct sigaction sa;

    };

    #else

    struct sigaction {

    union {

    __sighandler_t _sa_handler;

    void (*_sa_sigaction)(int, struct siginfo *, void *);

    } _u;

    sigset_t sa_mask;

    unsigned long sa_flags;

    void (*sa_restorer)(void);

    };

    #define sa_handler _u._sa_handler

    #define sa_sigaction _u._sa_sigaction

    #endif

    sa_handler的原型是一个参数为int,返回类型为void的函数指针。参数即为信号值,所以信号不能传递除信号值之外的任何信息;

    sa_sigaction 的原型是一个带三个参数,类型分别为int,struct siginfo *,void

    *,返回类型为void的函数指针。第一个参数为信号值;第二个参数是一个指向struct

    siginfo结构的指针,此结构中包含信号携带的数据值;第三个参数没有使用。

    sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。默认当前信号本身被阻塞。

    sa_flags

    包含了许多标志位,比较重要的一个是SA_SIGINFO,当设定了该标志位时,表示信号附带的参数可以传递到信号处理函数中。即使

    sa_sigaction指定信号处理函数,如果不设置SA_SIGINFO,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信息的访问都将导致段错误。

    sa_restorer已过时,POSIX不支持它,不应再使用。

    因此,当你的信号需要接收附加信息的时候,你必须给sa_sigaction赋信号处理函数指针,同时还要给sa_flags赋SA_SIGINFO,类似下面的代码:

    #include

    ……

    void sig_handler_with_arg(int sig,siginfo_t *sig_info,void

    *unused){……}

    int main(int argc,char **argv)

    {

    struct sigaction sig_act;

    ……

    sigemptyset(&sig_act.sa_mask);

    sig_act.sa_sigaction=sig_handler_with_arg;

    sig_act.sa_flags=SA_SIGINFO;

    ……

    }

    如果你的应用程序只需要接收信号,而不需要接收额外信息,那你需要的设置的是sa_handler,而不是sa_sigaction,你的程序可能类似下面的代码:

    #include

    ……

    void sig_handler(int sig){……}

    int main(int argc,char **argv)

    {

    struct sigaction sig_act;

    ……

    sigemptyset(&sig_act.sa_mask);

    sig_act.sa_handler=sig_handler;

    sig_act.sa_flags=0;

    ……

    }

    如果需要更详细说明,请参阅sigaction的man手册。

    补充:

    简而言之就是:

    //自定义退出函数

    sigact.sa_handler = mysighandler;

    sigemptyset(&sigact.sa_mask);

    sigact.sa_flags = 0;

    sigaction(SIGINT, &sigact, NULL);

    sigaction(SIGTERM, &sigact, NULL);

    sigaction(SIGQUIT, &sigact, NULL);

    或者利用signal函数进行信号捕捉:

    void (*signal(int signo, void (*handler)(int)))(int);

    当signal到来时,程序运行某函数,函数由你自己指定。

    附带各种信号定义:

    在终端使用kill -l 命令可以显示所有的信号。

    $kill -l

    1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL

    5) SIGTRAP 6) SIGABRT 7) SIGBUS

    a4c26d1e5885305701be709a3d33442f.png

    SIGFPE

    9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2

    13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT

    17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP

    21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU

    25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH

    29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN

    35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4

    39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8

    43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46)

    SIGRTMIN+12

    47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50)

    SIGRTMAX-14

    51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54)

    SIGRTMAX-10

    55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6

    59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2

    63) SIGRTMAX-1 64) SIGRTMAX

    其中前面31个信号为不可靠信号(非实时的,可能会出现信号的丢失),后面的信号为可靠信号(实时的real_time,对信号

    排队,不会丢失)。

    1) SIGHUP (挂起) 当运行进程的用户注销时通知该进程,使进程终止

    2) SIGINT (中断) 当用户按下时,通知前台进程组终止进程

    3) SIGQUIT (退出) 用户按下或时通知进程,使进程终止

    4) SIGILL (非法指令) 执行了非法指令,如可执行文件本身出现错误、试图执行数据段、堆栈溢出

    5) SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用

    6) SIGABRT (异常中止) 调用abort函数生成的信号

    7) SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长的整数,

    但其地址不是4的倍数.

    8) SIGFPE (算术异常) 发生致命算术运算错误,包括浮点运算错误、溢出及除数为0.

    9) SIGKILL (确认杀死) 当用户通过kill -9命令向进程发送信号时,可靠的终止进程

    10) SIGUSR1 用户使用

    11) SIGSEGV (段越界) 当进程尝试访问不属于自己的内存空间导致内存错误时,终止进程

    12) SIGUSR2 用户使用

    13) SIGPIPE 写至无读进程的管道, 或者Socket通信SOCT_STREAM的读进程已经终止,而再写入。

    14) SIGALRM (超时) alarm函数使用该信号,时钟定时器超时响应

    15) SIGTERM (软中断) 使用不带参数的kill命令时终止进程

    17) SIGCHLD (子进程结束) 当子进程终止时通知父进程

    18) SIGCONT (暂停进程继续) 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞.

    19) SIGSTOP (停止) 作业控制信号,暂停停止(stopped)进程的执行. 本信号不能被阻塞, 处理或忽略.

    20) SIGTSTP (暂停/停止) 交互式停止信号, Ctrl-Z 发出这个信号

    21) SIGTTIN 当后台作业要从用户终端读数据时, 终端驱动程序产生SIGTTIN信号

    22) SIGTTOU 当后台作业要往用户终端写数据时, 终端驱动程序产生SIGTTOU信号

    23) SIGURG 有"紧急"数据或网络上带外数据到达socket时产生.

    24) SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/改变。

    25) SIGXFSZ 当进程企图扩大文件以至于超过文件大小资源限制。

    26) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.

    27) SIGPROF (梗概时间超时) setitimer(2)函数设置的梗概统计间隔计时器(profiling interval

    timer)

    28) SIGWINCH 窗口大小改变时发出.

    29) SIGIO(异步I/O) 文件描述符准备就绪, 可以开始进行输入/输出操作.

    30) SIGPWR 电源失效/重启动

    31) SIGSYS 非法的系统调用。

    在以上列出的信号中,

    程序不可捕获、阻塞或忽略的信号有:SIGKILL,SIGSTOP

    不能恢复至默认动作的信号有:SIGILL,SIGTRAP

    默认会导致进程流产的信号有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ

    默认会导致进程退出的信号有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM

    默认会导致进程停止的信号有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU

    默认进程忽略的信号有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH

    此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在进程挂起时是继续,否则是忽略,不能被阻塞。

    在Unix/Linux中signal函数是比较复杂的一个,其定义原型如下:

    void (*signal(int signo,void (*func)(int))) (int)

    这个函数中,最外层的函数体

    void (* XXX

    )(int)表明是一个指针,指向一个函数XXX的指针,XXX所代表的函数需要一个int型的参数,返回void

    signal(int signo, void(*func)(int))是signal函数的主体.

    需要两个参数int型的signo以及一个指向函数的函数.

    void (*func)(int).

    正是由于其复杂性,在[Plauger 1992]用typedef来对其进行简化

    typedef void Sigfuc(int);//这里可以看成一个返回值 .

    再对signal函数进行简化就是这样的了

    Sigfunc *signal(int,Sigfuc *);

    在signal.h头文件中还有以下几个定义

    #define SIG_ERR (void (*)())-1

    #define SIG_DFL (void (*)())0

    #define SIG_IGN (void (*)())1

    处理不当导致的问题请参照下面网址

    http://www.diybl.com/course/3_program/c++/cppjs/20090831/173152.html

    分享:

    a4c26d1e5885305701be709a3d33442f.png喜欢

    0

    a4c26d1e5885305701be709a3d33442f.png赠金笔

    加载中,请稍候......

    评论加载中,请稍候...

    发评论

    登录名: 密码: 找回密码 注册记住登录状态

    昵   称:

    评论并转载此博文

    a4c26d1e5885305701be709a3d33442f.png

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

    展开全文
  • sigaction介绍

    千次阅读 2017-08-04 14:58:35
    sigaction 原型: int sigaction(int signo,const struct sigaction *restrict act, struct sigaction *restrict oact); @signo 信号编号 @act 要注册的信号动作 @oact 原信号动作

    sigaction

    原型:
    int sigaction(int signo,const struct sigaction *restrict act, struct sigaction *restrict oact);
    @signo 信号编号
    @act 要注册的信号动作
    @oact 原信号动作

    参数 struct sigaction

    struct sigaction{
    void (*sa_handler)(int);
    sigset_t sa_mask;
    int sa_flag;
    void (sa_sigaction)(int,siginfo_t ,void *);
    };

    sa_haddler or sa_sigaction

    sa_handler & sa_sigaction 信号处理函数的指针,二者用其一:如果sa_flags中存在SA_SIGINFO标志,那么sa_sigaction将作为signum信号的处理函数。否则用sa_handler。

    sa_mask

    sa_mask 指定一个系统在处理该信号时要屏蔽(阻塞)的信号集合,即在调用该信号捕捉函数之前,这一信号集要加进进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值。另外,除了SA_NODEFER标志被指定外,触发信号处理函数执行的那个信号也会被阻塞。

    sa_flag

    sa_flag 指定一系列用于修改信号处理过程行为的标志,由下面的0个或多个标志通过or运算组合而成:
    SA_SIGINFO 指定信号处理函数需要三个参数,所以应使用sa_sigaction替代sa_handler。
    SA_NODEFER 在信号处理函数处置信号的时段中,核心程序不会把这个间隙中产生的信号阻塞。
    SA_INTERRUPT 由此信号中断的系统调用不会自动重启
    SA_RESTART 核心会自动重启信号中断的系统调用,否则返回EINTR错误值。(重启被中断的系统调用)
    SA_RESETHAND 信号处理函数接收到信号后,会先将对信号处理的方式设为预设方式,而且当函数处理该信号时,后来发生的信号将不会被阻塞。
    SA_ONSTACK 如果利用sigaltstack()建立信号专用堆栈,则此标志会把所有信号送往该堆栈。
    SA_NOCLDSTOP 假如signum的值是SIGCHLD,则在子进程停止或恢复执行时不会传信号给调用本系统调用的进程。
    SA_NOCLDWAIT 当调用此系统调用的进程之子进程终止时,系统不会建立zombie进程。

    示例

    #include <signal.h>
    #include <stdio.h>
    #include <unistd.h>
    
    
    void signal_handler(int sig)
    {
        printf(">>>>>>>>>>>new signal %d\n", sig);
    
        int i = 0;
        for (i = 0; i < 5; i++)
        {
            printf("signal func %d\n", i);
            sleep(1);
        }
    }
    
    int main()
    {
        struct sigaction act;
        act.sa_handler = signal_handler;
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask, SIGQUIT);
        // act.sa_flags = SA_RESETHAND;
        // act.sa_flags = SA_NODEFER;
        act.sa_flags = 0;
    
        sigaction(SIGINT, &act, 0);
    
    
        struct sigaction act_2;
        act_2.sa_handler = signal_handler;
        sigemptyset(&act_2.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGQUIT, &act_2, 0);
    
        while(1)
        {
             sleep(1);
        }
        return;
    
    }
    1. 阻塞,sigaction函数有阻塞的功能,比如SIGINT信号来了,进入信号处理函数,默认情况下,在信号处理函数未完成之前,如果又来了一个SIGINT信号,其将被阻塞,只有信号处理函数处理完毕,才会对后来的SIGINT再进行处理,同时后续无论来多少个SIGINT,仅处理一个SIGINT,sigaction会对后续SIGINT进行排队合并处理。

    2. sa_mask,信号屏蔽集,可以通过函数sigemptyset/sigaddset等来清空和增加需要屏蔽的信号,上面代码中,对信号SIGINT处理时,如果来信号SIGQUIT,其将被屏蔽,但是如果在处理SIGQUIT,来了SIGINT,则首先处理SIGINT,然后接着处理SIGQUIT。

    3. sa_flags如果取值为0,则表示默认行为。还可以取如下俩值,但是我没觉得这俩值有啥用。

    SA_NODEFER,如果设置来该标志,则不进行当前处理信号到阻塞

    SA_RESETHAND,如果设置来该标志,则处理完当前信号后,将信号处理函数设置为SIG_DFL行为

    信号

    1. SIGQUIT:
      在POSIX兼容的平台,SIGQUIT是其控制终端发送到进程,当用户请求的过程中执行核心转储的信号。 SIGQUIT通常可以ctrl+ \。在Linux上,人们还可以使用Ctrl-4或虚拟控制台,SysRq yek。

    2. SIGTERM:
      SIGTERM是杀或的killall命令发送到进程默认的信号。它会导致一过程的终止,但是SIGKILL信号不同,它可以被捕获和解释(或忽略)的过程。因此,SIGTERM类似于问一个进程终止可好,让清理文件和关闭。因为这个原因,许多Unix系统关机期间,初始化问题SIGTERM到所有非必要的断电过程中,等待几秒钟,然后发出SIGKILL强行终止仍然存在任何这样的过程。

    3. SIGINT:
      符合POSIX平台,信号情报是由它的控制终端,当用户希望中断该过程发送到处理的信号。通常ctrl-C,但在某些系统上,“删除”字符或“break”键 - 当进程的控制终端的用户按下中断正在运行的进程的关键SIGINT被发送。

    4. SIGKILL:
      上符合POSIX平台上,SIGKILL是发送到处理的信号以使其立即终止。当发送到程序,SIGKILL使其立即终止。在对比SIGTERM和SIGINT,这个信号不能被捕获或忽略,并且在接收过程中不能执行任何清理在接收到该信号。

    SIGHUP 终止进程 终端线路挂断
    SIGINT 终止进程 中断进程
    SIGQUIT 建立CORE文件终止进程,并且生成core文件
    SIGILL 建立CORE文件 非法指令
    SIGTRAP 建立CORE文件 跟踪自陷
    SIGBUS 建立CORE文件 总线错误
    SIGSEGV 建立CORE文件 段非法错误
    SIGFPE 建立CORE文件 浮点异常
    SIGIOT 建立CORE文件 执行I/O自陷
    SIGKILL 终止进程 杀死进程
    SIGPIPE 终止进程 向一个没有读进程的管道写数据
    SIGALARM 终止进程 计时器到时
    SIGTERM 终止进程 软件终止信号
    SIGSTOP 停止进程 非终端来的停止信号
    SIGTSTP 停止进程 终端来的停止信号
    SIGCONT 忽略信号 继续执行一个停止的进程
    SIGURG 忽略信号 I/O紧急信号
    SIGIO 忽略信号 描述符上可以进行I/O
    SIGCHLD 忽略信号 当子进程停止或退出时通知父进程
    SIGTTOU 停止进程 后台进程写终端
    SIGTTIN 停止进程 后台进程读终端
    SIGXGPU 终止进程 CPU时限超时
    SIGXFSZ 终止进程 文件长度过长
    SIGWINCH 忽略信号 窗口大小发生变化
    SIGPROF 终止进程 统计分布图用计时器到时
    SIGUSR1 终止进程 用户定义信号1
    SIGUSR2 终止进程 用户定义信号2
    SIGVTALRM 终止进程 虚拟计时器到时

    1) SIGHUP 本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控
    制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端
    不再关联.
    2) SIGINT 程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出
    3) SIGQUIT 和SIGINT类似, 但由QUIT字符(通常是Ctrl-)来控制. 进程在因收到
    SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信
    号.
    4) SIGILL 执行了非法指令. 通常是因为可执行文件本身出现错误, 或者试图执行
    数据段. 堆栈溢出时也有可能产生这个信号.
    5) SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用.
    6) SIGABRT 程序自己发现错误并调用abort时产生.
    6) SIGIOT 在PDP-11上由iot指令产生, 在其它机器上和SIGABRT一样.
    7) SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长
    的整数, 但其地址不是4的倍数.
    8) SIGFPE 在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢
    出及除数为0等其它所有的算术的错误.
    9) SIGKILL 用来立即结束程序的运行. 本信号不能被阻塞, 处理和忽略.
    10) SIGUSR1 留给用户使用
    11) SIGSEGV 试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据.
    12) SIGUSR2 留给用户使用
    13) SIGPIPE Broken pipe
    14) SIGALRM 时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该
    信号.
    15) SIGTERM 程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和
    处理. 通常用来要求程序自己正常退出. shell命令kill缺省产生这
    个信号.
    17) SIGCHLD 子进程结束时, 父进程会收到这个信号.
    18) SIGCONT 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞. 可以用
    一个handler来让程序在由stopped状态变为继续执行时完成特定的
    工作. 例如, 重新显示提示符
    19) SIGSTOP 停止(stopped)进程的执行. 注意它和terminate以及interrupt的区别:
    该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略.
    20) SIGTSTP 停止进程的运行, 但该信号可以被处理和忽略. 用户键入SUSP字符时
    (通常是Ctrl-Z)发出这个信号
    21) SIGTTIN 当后台作业要从用户终端读数据时, 该作业中的所有进程会收到SIGTTIN
    信号. 缺省时这些进程会停止执行.
    22) SIGTTOU 类似于SIGTTIN, 但在写终端(或修改终端模式)时收到.
    23) SIGURG 有”紧急”数据或out-of-band数据到达socket时产生.
    24) SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/
    改变
    25) SIGXFSZ 超过文件大小资源限制.
    26) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.
    27) SIGPROF 类似于SIGALRM/SIGVTALRM, 但包括该进程用的CPU时间以及系统调用的
    时间.
    28) SIGWINCH 窗口大小改变时发出.
    29) SIGIO 文件描述符准备就绪, 可以开始进行输入/输出操作.
    30) SIGPWR Power failure

    有两个信号可以停止进程:SIGTERM和SIGKILL。 SIGTERM比较友好,进程能捕捉这个信号,根据您的需要来关闭程序。在关闭程序之前,您可以结束打开的记录文件和完成正在做的任务。在某些情况下,假如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号。

    对于SIGKILL信号,进程是不能忽略的。这是一个 “我不管您在做什么,立刻停止”的信号。假如您发送SIGKILL信号给进程,Linux就将进程停止在那里。

    参考链接:
    http://blog.csdn.net/beginning1126/article/details/8680757
    http://blog.csdn.net/ordeder/article/details/50809660
    http://blog.csdn.net/dai_xiangjun/article/details/41871647
    http://www.cnblogs.com/dzhs/p/5388092.html

    展开全文
  • 函数sigaction

    2020-06-04 14:35:09
    函数sigaction、signal
  • sigaction 使用

    千次阅读 2016-03-05 16:55:54
    函数sigaction原型:int sigaction(int signo,const struct sigaction *restrict act, struct sigaction *restrict oact); @signo 信号编号 @act 要注册的信号动作 @oact 原信号动作 参数 struct sigactionstruct...
  • sigaction函数

    2018-09-05 21:42:00
    sigaction函数是设置信号处理的接口。比signal函数更健壮 #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); signu...
  • sigprocmask sigaction

    2018-11-23 13:00:28
    sigaction : signal增强版本, 当处理信号时, 可以随意添加信号屏蔽字 sigset_t newmask,oldmask,pendmask; signal(SIGINT,sig_handler); sigemptyset(&amp;newmask); sigaddset(&amp;...
  • sigaction 函数

    千次阅读 2016-09-07 10:23:32
    linux 信号的使用,推荐用sigaction
  • sigaction 函数原型定义如下:  int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact)  这个系统调用的作用是改变进程接收到的指定信号的行动。  使用这个函数需要包含头文件#...
  • linux sigaction

    2018-06-12 11:56:44
    在linux做socket通信时,服务器断开连接,客户端send数据会导致客户端进程退出,解决办法,客户端进程忽略信号SIGPIPE=13 struct sigaction sa; sa.sa_handler = SIG_IGN; sigaction( SIGPIPE, &amp;sa, 0 );...
  • 实际上,C 语言程序中的任何一个标识符在编译之后都对应于一个内存地址,也就是说,函数名是一个地址、结构体也是一个地址, 但是,“int sigaction(int signum,const struct sigaction *act ,struct sigaction *...
  • sigaction和sigqueue

    2017-01-12 20:50:22
    sigaction和signal一样用来注册信号处理函数,siqqueue和kill一样,用来发送信号,但是sigaction比signal功能强大,signal比较简单。 int sigaction(int signum, const struct sigaction *act, struct sigaction*...
  • sigaction函数纪要

    2018-11-28 13:21:13
    创建于 2012-06-01 迁移自个人的百度空间 -------------------------...int sigaction(int signum, const struct sigaction *act , struct sigaction *oldact); //查询或设置信号处理方式 函数说明:  ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,925
精华内容 7,970
关键字:

sigaction