zoukankan      html  css  js  c++  java
  • 第二十四篇:可靠信号机制

    前言

           曾经的 UNIX 系统中,信号的不可靠的。什么是不可靠?就是信号丢失呗。那什么是信号丢失?就是当系统正在处理某个事务的时候,如果收到了某个信号,但它不能及时处理这个信号,那么只能忽略掉此信号

           而在可靠信号机制中,如果发生了上述情况,则要求系统处理完当前的事务后,还能够找回丢失的那个信号。也就是说,要具备本文即将讲述的 - 信号的阻塞功能。

    信号的阻塞

           系统在信号发生后,会在进程表中设置一个标志。在信号发生到进程表中设置一个标志的时间间隔之内,我们称信号是未决的。所谓信号阻塞,就是指将信号保持未决状态,直到用户将信号解除阻塞,该信号才被接收。

    重要概念:信号集

           信号集是一种数据类型,它能够表述系统内所有的信号:类似位图,某位为 1 表示该位对应的信号存在(被屏蔽),反之不存在(未被屏蔽)。对此数据类型的操作需要使用下表所提供的函数来进行:

           

    大致步骤

           1. 保存当前信号屏蔽集

           2. 定义新的信号屏蔽集

           3. 使新的信号屏蔽集生效

           4. 恢复原来的信号屏蔽集

           这四个步骤,所涉及到的只有一个函数:sigprocmask 函数,该函数的详细说明请参考相关文档。

    代码实现

           如下示例程序首先执行上述的步骤 1 2 3( 屏蔽退出信号 ),然后挂起 5 秒钟,然后在此期间产生 3 次退出信号,再执行上述步骤 4,最后再挂起 5 秒钟:

     1 #include <stdio.h>
     2 #include <unistd.h>
     3 #include <signal.h>
     4 
     5 // 信号处理函数( 此类函数都是无返回且形参为一个整数,该整数即为所接收到的信号 )
     6 static void sig_quit (int);
     7 
     8 int main (void) {
     9     
    10     // 定义信号集
    11     sigset_t newmask, oldmask, pendmask;
    12 
    13     // 注册退出信号处理函数
    14     if (signal(SIGQUIT, sig_quit) == SIG_ERR) {
    15         printf("注册信号处理函数失败
    ");
    16         return 1;
    17     }
    18 
    19     // 创建一个新的信号屏蔽字
    20     sigemptyset(&newmask);
    21     sigaddset(&newmask, SIGQUIT);
    22 
    23     // 屏蔽退出信号,并将原来的信号屏蔽字保存起来。
    24     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
    25         printf("屏蔽退出信号失败
    ");
    26         return 2;
    27     }
    28 
    29     printf("已屏蔽退出信号
    ");
    30 
    31     sleep(5);
    32 
    33     // 恢复原来的信号屏蔽字
    34     printf("
    接下来恢复原来的信号屏蔽字
    ");
    35     if (sigprocmask(SIG_SETMASK, &oldmask, 0) < 0) {
    36         printf("恢复信号屏蔽字失败
    ");
    37         return 2;
    38     }
    39 
    40     sleep(5);
    41 
    42     return 0;
    43 }
    44 
    45 static void sig_quit (int signo)
    46 {
    47     printf("捕捉到退出信号
    ");
    48 
    49     // 将对退出信号的处理设置为关闭进程
    50     if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) {
    51         printf("设置退出信号处理函数失败
    ");
    52     }
    53 }

    运行测试

           

           第一次睡眠时,我发出了三次退出信号,结果只接收并处理了一次( 假如接收了两次,则第二次就会结束掉进程了。)。

           当恢复到之前的信号屏蔽字以后,我再发出退出信号,进程立刻就关闭了。

    小结

           1. 可靠信号可靠之处在于可以使信号阻塞,到合适的时候再解除阻塞,接收信号。

           2. 使用 sigaction 函数实现可靠信号更加方便。

  • 相关阅读:
    优秀网站推荐
    本机号码一键登录
    基金配置#通过且慢分析基金相关性
    开源didi kafka-manager使用
    多线程编程解决思路
    jsoup选择器
    codeman的角色权限显隐
    html页面跳转带中文参数,乱码
    idea代码查看当前项目占用内存
    阿里云oss上传———通过MultipartFile,springmvc模式
  • 原文地址:https://www.cnblogs.com/muchen/p/6354594.html
Copyright © 2011-2022 走看看