• sigpending


    信号的阻塞:通过sigprocmask()将信号集sigset_t中的信号设置为阻塞。SIG_BLOCK是指对相应信号的“递送阻塞”,内核在递送一个原来被阻塞的信号给进程时(而不是在产生该信号时),才决定对它的处理方式,那么进程在信号递送给它之前仍可改变对该信号的动作。

    一个信号的"生命周期"为:产生(generation)、未决(pending)、递送(delivery)

    如果将信号设置为阻塞,那么,在信号产生和递送之间的时间间隔内,称信号是未决的(pending)。 

    如果信号被设置成阻塞,且该信号的动作是系统默认动作或捕获该信号,当该信号产生后,则进程将此信号的状态保持为未决(pending)状态,直到对该信号解除了阻塞或将该信号的动作改为忽略。

    sigpending函数的作用是获取被设置为SIG_BLOCK的信号集。

    1 static void sig_quit(int signo)
    2 {
    3     printf("111caught SIGQUIT
    ");
    4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
    5     {
    6         printf("can't reset SIGQUIT
    ");
    7     }
    8 }
     1 int main(int argc, char** argv)
     2 {
     3     sigset_t newmask, oldmask, pendmask;
     4 
     5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
     6     {
     7         printf("can't catch SIGQUIT
    ");    
     8         return -1;
     9     }
    10 
    11     //block SIGQUIT and save cureent signal mask
    12     sigemptyset(&newmask);
    13     sigaddset(&newmask, SIGQUIT);
    14 
    15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
    16     {
    17         printf("SIGBLCOK error
    ");    
    18         return -1;
    19     }
    20     printf("newmask:%x, oldmask:%x
    ", newmask, oldmask);
    21 
    22     sleep(5);
    23     
    24     if (sigpending(&pendmask)<0)
    25     {
    26         printf("sigpending error
    ");    
    27         return -1;
    28     }
    29     printf("pendmask:%x
    ", pendmask);
    30 
    31     if (sigismember(&pendmask, SIGQUIT))
    32         printf("SIGQUIT pending
    ");    
    33 
    34     if (sigprocmask(SIG_SETMASK, &oldmask, NULL))//解除阻塞
    35     {
    36         printf("sigprocmask error
    ");
    37         return -1;
    38     }
    39     printf("222SIGQUIT unblock
    ");
    40 
    41     sleep(5);
    42 
    43     return 0;
    44 }

    运行结果为:

    1. 当在第一个sleep 5s期间,Ctrl+ 产生SIGQUIT信号时:

    因为在sleep期间产生了SIGQUIT信号,那么此时该信号的状态时pending的,当该信号被设置为不阻塞后,即解除阻塞后,立即捕获该信号。从输出中可以看出,sig_quit中的printf语句先执行,然后再执行sigprocmask之后的printf语句。

    2. 如果在第一个sleep 5s期间,不产生SIGQUIT信号,显然,sigpending的输出为0。

    从结果中可以看到,本次pendmask为0,而上次pendmask为4。

    SIG_BLOCK是指对相应信号的“递送阻塞”,内核在递送一个原来被阻塞的信号给进程时(而不是在产生该信号时),才决定对它的处理方式,那么进程在信号递送给它之前仍可改变对该信号的动作。

    1 static void sig_quit(int signo)
    2 {
    3     printf("111caught SIGQUIT
    ");
    4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
    5     {
    6         printf("can't reset SIGQUIT
    ");
    7     }
    8 }
    1 static void sig_quit2(int signo)
    2 {
    3     printf("xxxcaught SIGQUIT
    ");
    4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
    5     {
    6         printf("can't reset SIGQUIT
    ");
    7     }
    8 }
     1 int main(int argc, char** argv)
     2 {
     3     sigset_t newmask, oldmask, pendmask;
     4 
     5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
     6     {
     7         printf("can't catch SIGQUIT
    ");    
     8         return -1;
     9     }
    10 
    11     //block SIGQUIT and save cureent signal mask
    12     sigemptyset(&newmask);
    13     sigaddset(&newmask, SIGQUIT);
    14 
    15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
    16     {
    17         printf("SIGBLCOK error
    ");    
    18         return -1;
    19     }
    20     printf("newmask:%x, oldmask:%x
    ", newmask, oldmask);
    21 
    22     sleep(5);
    23     
    24     if (signal(SIGQUIT, sig_quit2) == SIG_ERR)
    25     {
    26         printf("can't catch SIGQUIT
    ");    
    27         return -1;
    28     }
    29 
    30     if (sigpending(&pendmask)<0)
    31     {
    32         printf("sigpending error
    ");    
    33         return -1;
    34     }
    35     printf("pendmask:%x
    ", pendmask);
    36 
    37     if (sigismember(&pendmask, SIGQUIT))
    38         printf("SIGQUIT pending
    ");    
    39 
    40     if (sigprocmask(SIG_SETMASK, &oldmask, NULL))
    41     {
    42         printf("sigprocmask error
    ");
    43         return -1;
    44     }
    45     printf("222SIGQUIT unblock
    ");
    46 
    47     sleep(5);
    48 
    49     return 0;
    50 }

    运行结果为:

    在line24中,又重新设置的SIGQUIT的信号处理程序。

    如果信号被设置成阻塞,且该信号的动作是系统默认动作或捕获该信号,当该信号产生后,则进程将此信号的状态保持为未决(pending)状态,直到对该信号解除了阻塞或将该信号的动作改为忽略

     1 int main(int argc, char** argv)
     2 {
     3     sigset_t newmask, oldmask, pendmask;
     4 
     5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
     6     {
     7         printf("can't catch SIGQUIT
    ");    
     8         return -1;
     9     }
    10 
    11     //block SIGQUIT and save cureent signal mask
    12     sigemptyset(&newmask);
    13     sigaddset(&newmask, SIGQUIT);
    14 
    15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
    16     {
    17         printf("SIGBLCOK error
    ");    
    18         return -1;
    19     }
    20     printf("newmask:%x, oldmask:%x
    ", newmask, oldmask);
    21 
    22     sleep(5);
    23     
    24     if (sigpending(&pendmask)<0)
    25     {
    26         printf("sigpending error
    ");    
    27         return -1;
    28     }
    29     printf("pendmask:%x
    ", pendmask);
    30 
    31     if (sigismember(&pendmask, SIGQUIT))
    32         printf("SIGQUIT pending
    ");    
    33 
    34     if (signal(SIGQUIT, SIG_IGN) == SIG_ERR)
    35     {
    36         printf("can't catch SIGQUIT
    ");    
    37         return -1;
    38     }
    39     printf("SIGQUIT IGNORE");
    40 
    41     sleep(5);
    42 
    43     return 0;
    44 }

    运行结果为:

  • 相关阅读:
    selfhacking第六天
    Emacshacking第二天
    有符号数和无符号数在计算机中的存储方式以及在Verilog中的运用($signed函数)
    网络资源
    Asp.Net MVC 之 Autofac 初步使用1
    Asp.Net MVC 之 Autofac 初步使用3 集成web api
    Silverligth API for ArcGIS应用程序IIS发布
    WebContent的红色小叉
    [转载]2229岁的人怎么工作?
    Flex+Java 开发环境部署之一:JDK
  • 原文地址:https://www.cnblogs.com/black-mamba/p/6848998.html
Copyright © 2020-2023  润新知