zoukankan      html  css  js  c++  java
  • 15信号sigaction

    信号处理

    信号值小于 SIGRTMIN 的信号 (1~31) 都是不可靠信号

    某些unix版本中,调用信号函数处理后会自动恢复默认信号处理,所以在信号处理函数中还需要继续调用signal函数设置信号处理

    这个问题在linux中并不存在

    linux 信号处理使用 sigaction函数,

    sigaction 与 signal

    主要优点: sigaction 支持参数传递

    简单运用,作用与signal相同

    void simFun(int sig)

    {   

          printf("receive sig=%d ",sig);

    }

    void testSigaction()

    {

          printf("pid=%d ",getpid());

          struct sigaction act,old;

          act.sa_handler=simFun;

          sigaction(SIGUSR1,&act,&old);

         

          while(1);

    }

    发出信号SIGUSR1,自动响应simFun处理函数。

    信号处理 

    int sigaction(int sig,  struct sigaction *act, struct sigaction *oldact)

    sig :指定捕获的信号

    act :指定捕获信号后的处理方式

    oldact:  上一次指定的处理方式

    信号处理

    struct sigaction

    {

    #ifdef __USE_POSIX199309

        union {

                  __sighandler_t sa_handler;        /* void(*)(int)  -- if SA_SIGINFO is not set.  */

                  void (*sa_sigaction) (int sig, siginfo_t *, void *); /* Used if SA_SIGINFO is set.  */

              }__sigaction_handler;

    # define sa_handler     __sigaction_handler.sa_handler

    # define sa_sigaction   __sigaction_handler.sa_sigaction

    __sigset_t     sa_mask;          /* 信号处理时,那些信号被阻塞 (默认为当前信号阻塞)*/

    int            sa_flags;            /* 响应信号的其他行为,其中 SA_SIGINFO 标志位指定信号处理方法*/

    void             (*sa_restorer) (void);             /*过时,不再使用.  */

    };

    结构体参数:

    sa_mask

    sigaddset(&xx.sa_mask,  SIGINT)   增加阻塞中断信号

    sa_flags

    SA_NOCLDSTOP     (1)              子进程暂停时不发送SIGCHLD信号通知父进程,SIGSTOP  SIGTSTP  SIGTTIN  SIGTTOU                     

    SA_NOCLDWAIT     (2)         子进程结束时,不变为僵尸进程,针对SIGCHLD信号

    SA_SIGINFO       (4)            使用sa_sigaction方法处理信号

    SA_RESTART       (0x10000000)   被信号中断的系统处理会自动重启

    SA_NODEFER       (0x40000000)   处理某信号时,这个信号不再阻塞, 可重入

    SA_RESETHAND     (0x80000000)   捕获信号后,这个信号恢复缺省处理

    siginfo_t结构体:

    siginfo_t {

                   int      si_signo;    /* Signal number */

                   int      si_errno;    /* An errno value */

                   int      si_code;     /* Signal code */

                   int      si_trapno;   /* Trap number that caused

                                            hardware-generated signal

                                            (unused on most architectures) */

                   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 */

                   int      si_overrun;  /* Timer overrun count; POSIX.1b timers */

                   int      si_timerid;  /* Timer ID; POSIX.1b timers */

                   void    *si_addr;     /* Memory location which caused fault */

                   long     si_band;     /* Band event (was int in

                                            glibc 2.3.2 and earlier) */

                     int      si_fd;       /* File descriptor */

                   short    si_addr_lsb; /* Least significant bit of address

                                            (since Linux 2.6.32) */

               }

    int sigqueue(pid, sig, union sigval sgv)

    发送信号给进程,使用同 kill效果一样

    不同于kill 的地方,多了一个信号参数,  只能向某个进程发送信号,不能向进程组发送信号

    如:sigqueue(getpid(), SIGUSR1, sgv);给自己发SIGUSR1。

    union sigval

    {

          int    sival_int;

          void*  sival_ptr;

    }

    带参数的例子:

    void complexFun(int sig,siginfo_t *info,void *ex)

    {

          sleep(3);

          printf("receive sig=%d ",sig);

          printf("Sending process ID:%d ",info->si_pid);

          printf("Real user ID of sending process:%d ",info->si_uid);

          printf("extrc value:%d ",info->si_value.sival_int);     

    }

    void testSigaction()

    {

          printf("pid=%d ",getpid());

          struct sigaction act,old;

          //act.sa_handler=simFun;

          //sigaction(SIGUSR1,&act,&old);

         

          sigaddset(&act.sa_mask,SIGINT);          

         

          act.sa_flags|=SA_SIGINFO;

          act.sa_flags|=SA_NODEFER;

          act.sa_sigaction=complexFun;

          sigaction(SIGUSR1,&act,&old);   

          union sigval sgv;

          sgv.sival_int=123;

          sigqueue(getpid(), SIGUSR1, sgv);

         

          while(1);

    }

    SA_NODEFER       (0x40000000)   处理某信号时,这个信号不再阻塞, 可重入

    比如:同一个按钮连续按下10次,那么该按钮信号可能只响应5,6次,达不到10。设置该属性后,就可以达到10.达到阻塞后推迟响应的效果。

    sigqueue(getpid(), SIGUSR1, sgv);

    给某一进程发送信号,如例子中的给自己发出SIGUSR1信号,并传入额外的参数。

  • 相关阅读:
    ASP.NET Core WebAPI学习-4
    PIESDKDoNet二次开发配置注意事项
    PIE SDK影像快速拼接
    PIE SDK加载WMS服务数据
    PIE SDK加载自定义服务数据
    PIE SDK 距离分类和最大似然分类
    PIE SDK矢量点生成等值线、面
    PIE SDK与OpenCV结合说明文档
    C#录制声卡声音喇叭声音音箱声音
    C#录制屏幕采集系统桌面画面
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9216003.html
Copyright © 2011-2022 走看看