首先说明:现在大部分Unix系系统如Linux都已经实现可靠信号。
1~31信号与SIGRTMIN-SIGRTMAX之间并不是可靠信号与不可靠信号的区别,在大多数系统下他们都是可靠信号。
只不过:
1~31信号           
               
  ——不支持排队,为普通信号。(不能用于统计信号发生次数的情景。)
SIGRTMIN-SIGRTMAX信号
——支持排队,实时信号

不可靠信号

什么是不可靠信号:
不可靠的意思是信号可能丢失或者被错误处理。
在早起系统中,信号存在两大缺陷,导致了信号不可靠。

缺陷一:

    信号发生后,信号处理方式被重置为系统默认动作。依旧是说,signal函数知识把信号和我们的信号处理函数关联一次,在发生一次信号后,信号的处理方式就被重置为系统默认了。
    这就导致了信号处理函数必须使用如下代码:
int sig_int(); /* my signal handling function */
...
signal(SIGINT, sig_int); /* @1establish handler */
...
sig_int()
{
signal(SIGINT, sig_int); /* @2reestablish handler for next time */
...
./*process the signal ... */
...
}
    我们不得不在信号处理函数中再次使用signal()。
    但是,这样的处理并不能保证程序完全正确,因为在发生一次信号时,在我们开始调用sig_int函数,到执行sig_int函数中的signal函数(也就是我们@2代码)之间是有时间间隔的.如果在这段时间间隔里发生了再次发生了信号,那么针对这个信号的处理方式就是系统默认的方法了。
    所以早期的信号时不可靠的,因为他不能保证信号都使用正确的(我们期望的)处理方式进行处理。

缺陷二:

    信号对进程的控制能力差:
    早期系统实现中,当我们不希望信号发生时,进程无法关闭一个 信号,并在记录它的发生。
    很多时候我们有这样的需求,我们不希望信号打断某项的工作,但是当工作执行完后,又希望系统告诉我们这段时间内发生了什么信号。比如我们运行一段程序,要求运行完之前不能中断它(比如我们的Ctl+C),这是就需要暂时关闭这个信号。
    首先我们明确需求,我们需要的是,信号暂时不起作用,并在之后能够提醒我们信号发生过。
    为了实现这一点,我们使用下面代码
int sig_int();     /* my signal handling function */
int sig_int_flag; /* set nonzero when signal occurs */
main()
{
    signal(SIGINT, sig_int); /* establish handler */
    ...
    while (sig_int_flag == 0)
        pause(); /* go to sleep, waiting for signal */
    ...
}
sig_int()
{
    signal(SIGINT, sig_int); /* reestablish handler for next time */
    sig_int_flag = 1; /* set flag for main loop to examine */
}
    sig_int只有两行代码,它的作用就是忽略信号,并且用sig_int_flag标志信号发生过。
    之所以用while只因为pause可能会被其他信号中断。(我的理解)
    
    在这段代码中仍然有缺陷,在while测试后,pause之前有一段时间间隔, 在这段时间间隔里如果信号发生,并且此后不再发生,则进程会一直进入睡眠状态。

可靠信号:

    可靠信号针对解决不可靠信号的两点缺陷来理解:

解决不可靠信号缺陷一

    用sigaction代替signal
(在现代大多数系统中,signal也使用了sigaction实现,因此事可靠的。)建议尽可能使用sigaction替代signal,因为sigaction是同一的标准,可移植性强。
     一旦给信号被sigaction安装了一个动作,那么在sigaction调用显示改变它之前,这个信号动作将一直有效,也就是说不会执行一次就回复默认动作。这种处理方式不同于早期系统的信号不可靠的信号处理方式。可以说现在系统的信号处理方式是可靠的。
    关于sigaction与signal的更多介绍可参考本博相关博文。

解决不可靠信号缺陷二:

    用户可以通过sigprocmask、sigaction设置屏蔽字是信号阻塞。使信号处于pending状态,这样也就自然解决了缺陷二。
        
















APUE学习笔记——10.可靠信号与不可靠信号的更多相关文章

  1. APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause

    转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...

  2. APUE学习笔记——10 信号

    信号的基本概念     信号是软件中断,信号提供了解决异步时间的方法.     每一中信号都有一个名字,信号名以SIG开头. 产生信号的几种方式     很多条件可以产生信号:     终端交互:用户 ...

  3. APUE学习笔记——10.11~10.13 信号集、信号屏蔽字、未决信号

    如有转载,请注明出处:Windeal专栏 首先简述下几个概念的关系: 我们通过信号集建立信号屏蔽字,使得信号发生阻塞,被阻塞的信号即未决信号. 信号集: 信号集:其实就是一系列的信号.用sigset_ ...

  4. APUE学习笔记——10信号——信号接口函数 signal 和 sigaction

    signal函数     signal函数是早起Unix系统的信号接口,早期系统中提供不可靠的信号机制.在后来的分支中,部分系统使用原来的不可靠机制定义signal函数,如 Solaris 10 .而 ...

  5. APUE学习笔记——10.18 system函数 与waitpid

    system函数 system函数用方便在一个进程中执行命令行(一行shell命令). 用法如下: #include <stdio.h> #include <stdlib.h> ...

  6. APUE学习笔记——10.15 sigsetjmp和siglongjmp

    转载自:sigsetjmp使用方法 如侵犯您的权益,请联系:windeal12@qq.com sigsetjmp使用方法 分类: c/c++ linux2012-02-03 12:33 1252人阅读 ...

  7. thinkphp学习笔记10—看不懂的路由规则

    原文:thinkphp学习笔记10-看不懂的路由规则 路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INF ...

  8. 《C++ Primer Plus》学习笔记10

    <C++ Primer Plus>学习笔记10 <<<<<<<<<<<<<<<<<&l ...

  9. SQL反模式学习笔记10 取整错误

    目标:使用小数取代整数 反模式:使用Float类型 根据IEEE754标识,float类型使用二进制格式编码实数数据. 缺点:(1)舍入的必要性: 并不是所有的十进制中描述的信息都能使用二进制存储,处 ...

随机推荐

  1. 20145303刘俊谦 《Java程序设计》实验四 实验报告

    实验要求 完成实验.撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等).解决办法(空洞的方法如"查网络&q ...

  2. 20144303 《Java程序设计》第三周学习总结

    20144303 <Java程序设计>第三周学习总结 教材学习内容总结 •对象是存在的具体实体,具有明确的状态和行为,类是具有相同属性和行为的一组对象的集合,用于组合各个对象所共有操作和属 ...

  3. 20145240《网络对抗》逆向及Bof基础实践

    逆向及Bof基础实践 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包 ...

  4. c++ 使用WinHTTP实现文件下载功能

    因为要项目中要想要实现一个软件自动更新的功能,之前是使用socket直接下载.但切换下载源的时候很麻烦.所以换用http方式. 网上找了很多资料,基本上就是下面几种: 1.curllib //功能强大 ...

  5. 实现ModelDriver接口的功能(转)

    ModelDriver接口 来自com.opensymphony.xwork2.ModelDriven.是xwork-2.1.2-750.jar包的东西. 下面是源码: package com.ope ...

  6. Python学习札记(二) python3.5安装 + (假装是)第一个Python程序

    参考: Mac OS 安装 Python3.5 廖雪峰Python教程:安装Python 笔记: 安装: 1.官方网站下载安装包:安装程序 2.执行安装程序完成Python3.5包的安装. 3.安装P ...

  7. C# Winform实现手机号码归属地查询工具

    摘要:本文介绍使用C#开发基于Winform的手机号码归属地查询工具,并提供详细的示例代码供参考. 一.需求描述 输入正确的手机号码,查询该号码的归属地和其他相关信息. 二.需求分析 1.实现手机号码 ...

  8. 在lnmp下开启fileinfo扩展 Ubuntu系统

    在lnmp下开启fileinfo扩展 Ubuntu系统 1.进入目录下 cd /usr/local/lnmp1.4-full/src/php-5.6.31/ext/fileinfo 2.phpize处 ...

  9. Module 的加载实现

    浏览器加载 传统方法 HTML 网页中,浏览器通过<script>标签加载 JavaScript 脚本. <!-- 页面内嵌的脚本 --> <script type=&q ...

  10. Angular2 中的依赖包详解

    转自:http://blog.csdn.net/feiying008/article/details/53033704 目录 dependencies 和 devDependencies depend ...