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 函数实现可靠信号更加方便。

  • 相关阅读:
    开始学习编写用于 Windows SideShow 设备的小工具【转】
    Windows Mobile 6.5 Developer Tool Kit 下载
    Microsoft Security Essentials 微软免费杀毒软件下载
    SQL Server 2008 空间数据存储摘抄(SRID 点 MultiPoint LineString MultiLineString 多边形 MultiPolygon GeometryCollection)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (2)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (4)
    负载测试、压力测试和性能测试的异同
    Windows Server 2008 Vista Sidebar Gadget (侧边栏小工具) 入门开发实例
    Silverlight Tools 安装失败 解决办法
    SQL Server 2008 空间数据库 空间索引概念及创建(取自帮助)
  • 原文地址:https://www.cnblogs.com/muchen/p/6354594.html
Copyright © 2011-2022 走看看