这篇将一口气学完信号的基本概念,但是有很多的细节,所以篇幅较长,请做好心理准备。 (他大爷的,一口气没有学完,太懒了)

有以下主题:

  • 各种不同信号及其用途
  • 内核可能为进程产生信号的环境,以及某一进程向另一进程发送信号所使用的系统调用。
  • 进程在默认情况下对信号的响应方式,以及进程改变对信号响应方式的手段,特别是借助于信号处理器程序的手段,即程序收到信号时自动去调用的函数,由程序员定义。
  • 使用进程信号掩码来阻塞信号,以及等待信号的相关概念。
  • 如何暂停进程的执行,并等待信号的到达。

起始信号的概念还是挺简单的,但是没有写过代码练习这块的内容。不知道Java编程中有没有信号这种东西。

概念和概述

信号是事件发生时对进程的通知机制。有时也称之为软件中断。信号与硬件中断的相似之处在于打断了程序执行的正常流程,大多数情况下,无法预测信号到达的精确时间。

一个(具有合适权限的)进程能够向另一进程发送信号。信号的这一用法可作为一种同步技术,甚至是进程间通信(IPC)的原始形式。进程也可以向自身发送信号。然而,发往进程的诸多信号,通常都是源于内核。
引发内核为进程产生信号的各类事件如下。

  • 硬件发生异常,即硬件检测到一个错误条件并通知内核,随即再由内核发送相应信号给相关进程。硬件异常的例子包括执行一条异常的机器语言指令,诸如,被0除,或者引用了无法访问的内存区域。
  • 用户键入了能够产生信号的终端特殊字符。其中包括中断字符(通常是Control-C)、暂停字符(通常是Control-Z)。
  • 发生了软件事件。例如,针对文件描述符的输出变为有效,调整了终端窗口的大小,定时器到期,进程执行的CPU时间超限,或者该进程的某个子进程退出。

针对每个信号,都定义了一个唯一的(小)整数,从1开始顺序展开。<signal.h>以SIGxxxx形式的符号名对这些整数做了定义。由于每个信号的实际编号随系统不同而不同,所以在程序中总是使用这些符号名。例如,当用户键入中断字符时,将传递给进程SIGINT信号(信号编号为2)。

信号分为两大类。第一组用于内核向进程通知事件,构成所谓传统或者标准信号。Linux中标准信号的编号范围为1~31。另一组信号由实时信号构成,与标准信号的差异会在后面继续学习。

信号因某些事件而产生。信号产生后,会于稍后被传递给某一进程,而进程也会采取某些措施来来响应信号。在产生和到达期间,信号处于等待(pending)状态。

通常,一旦(内核)接下来要调度该进程运行,等待信号会马上送达,或者如果进程正在运行,则会立即传递信号(例如,进程向自身发送信号)。然而,有时需要确保一段代码不为传递来的信号所中断。为了做到这一点,可以将信号添加到进程的信号掩码中——目前会阻塞该组信号的到达。

如果所产生的信号属于阻塞之列,那么信号将保持等待状态,直至稍后对其解除阻塞(从信号掩码中移除)。进程可使用各种系统调用对其信号掩码添加和移除信号。

信号到达后,进程视具体信号执行如下默认操作之一。

  • 忽略信号:也就是说,内核将信号丢弃,信号对进程没有产生任何影响(进程永远都不知道曾经出现过该信号)。
  • 终止(杀死)进程:这有时是指进程异常终止,而不是进程因调用exit而发生的正常终止。
  • 产生核心转储文件,同时进程终止:核心转储文件包含对进程虚拟内存的镜像,可将其加载到调试器中以检查进程终止时的状态。
  • 停止进程:暂停进程的执行。
  • 于之前暂停后再度恢复进程的执行。

除了根据特定信号而采取默认行为之外,程序也能改变信号到达时的响应行为。也将此称之为对信号的处置(disposition)设置。程序可以将对信号的处置设置为如下之一。

  • 采取默认行为。这适用于撤销之前对信号处置的修改、恢复其默认处置的场景。
  • 忽略信号。这适用于默认行为为终止进程的信号。
  • 执行信号处理器程序。

信号处理器程序是由程序员编写的函数,用于为响应传递来的信号而执行适当任务。例如,shell为SIGINT信号(由中断字符串Control-C产生)提供了一个处理器程序,令其停止当前正在执行的工作,并将控制返回到(shell的)主输入循环,并再次向用户呈现shell提示符。通知内核应当去调用某一处理器程序的行为,通常称之为安装或者建立信号处理器程序。调用信号处理器程序以响应传递来的信号,则称之为信号已处理(handled),或者已捕获(caught)。

请注意,无法将信号处置设置为终止进程或者核心转储(除非这是对信号的默认处置)。效果最为近似的是为信号安装一个处理器程序,并于其中调用exit或者abort。abort函数为进程产生一个SIGABRT信号,该信号将引发进程转储核心文件并终止。

Linux特有的/proc/PID/status文件包含有各种位掩码字段,通过检查这些掩码可以确定进程对信号的处理。位掩码以十六进制数形式显示,最低有效位代表信号1,相临的左边一位代表信号2,以此类推。这些字段分别为SigPnd(基于线程的等待信号)、ShdPnd(进程级等待信号,始于Linux 2.6)、SigBlk(阻塞信号)、SigIgn(忽略信号)和SigCgt(捕获信号)。

信号在UNIX实现中出现很早,诞生之后又历经变革。在早期实现中,信号在特定场景下可能会丢失(即,没有传递到目标进程)。此外,尽管系统提供了关键代码时阻塞信号传递的机制,但阻塞有时也不大可靠。4.2BSD利用所谓可靠信号(可靠信号实现的?)解决了这些问题。(BSD在创新上还更进一步,增加了额外信号来支持shell作业控制。)

System V后来也为信号增加了可靠语义,但采用的模型与BSD无法兼容。这一不兼容性直到POSIX.1-1990标准出台后才得以解决。该标准针对可靠信号所采用的规范主要基于BSD模型。

Unix系统编程()信号:概念和概述的更多相关文章

  1. 《Linux/Unix系统编程手册》 时间子系统

    Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...

  2. 《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll

    关键词:fasync_helper.kill_async.sigsuspend.sigaction.fcntl.F_SETOWN_EX.F_SETSIG.select().poll().poll_wa ...

  3. 学习《Unix/Linux编程实践教程》(1):Unix 系统编程概述

    0.目录 1.概念 2.系统资源 3.学习方法 4.从用户的角度来理解 Unix 4.1 登录--运行程序--注销 4.2 目录操作 4.3 文件操作 5.从系统的角度来理解 Unix 5.1 网络桥 ...

  4. 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

    <Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...

  5. 《Linux/Unix系统编程手册》读书笔记6

    <Linux/Unix系统编程手册>读书笔记 目录 第9章 这章主要讲了一堆关于进程的ID.实际用户(组)ID.有效用户(组)ID.保存设置用户(组)ID.文件系统用户(组)ID.和辅助组 ...

  6. 《Linux/Unix系统编程手册》读书笔记1

    <Linux/Unix系统编程手册>读书笔记 目录 最近这一个月在看<Linux/Unix系统编程手册>,在学习关于Linux的系统编程.之前学习Linux的时候就打算写关于L ...

  7. 《Linux/UNIX系统编程手册》第56章 SOCKET:介绍

    关键词: 1. socket基础 一个典型的客户端/服务器场景中,应用程序使用socket进行通信的方式如下: 各个应用程序创建一个socket.socket是一个允许通信的设备,两个应用程序都需要用 ...

  8. 《Linux/Unix系统编程手册》读书笔记 目录

    <Linux/Unix系统编程手册>读书笔记1  (创建于4月3日,最后更新4月7日) <Linux/Unix系统编程手册>读书笔记2  (创建于4月9日,最后更新4月10日) ...

  9. 《Linux/Unix系统编程手册》读书笔记9(文件属性)

    <Linux/Unix系统编程手册>读书笔记 目录 在Linux里,万物皆文件.所以文件系统在Linux系统占有重要的地位.本文主要介绍的是文件的属性,只是稍微提及一下文件系统,日后如果有 ...

  10. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

随机推荐

  1. SpringSecurity实现后台管理员登录(二)

    需求:login.ftl页面中登录成功后进入index.ftl页面中 一.pom.xml中添加json转换相关的包 <dependency> <groupId>com.fast ...

  2. 解决Oracle监听错误的一种办法

    1:事出有因 安装oracle数据库,默认安装的是orcl数据库,安装完成后查看了一下字符集是gbk的,由于业务需要al32utf8的字符集,所以需要修改字符集,但是修改却无效.于是就删除了默认的or ...

  3. 已知m和n是两个整数,并且m^2+mn+n^2能被9整除,试证m,n都能被3整除。

    引证:m,n都是整数,m2=3n,求证m是3的倍数. 引证证明:(反证法)假设m并非3的倍数,那么m2则不含因数3,则m2≠3n,这与已知条件相反. 所以,当m2=3n时,m必是3的倍数. 有了引证, ...

  4. 算法笔记_134:字符串编辑距离(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 给定一个源串和目标串,能够进行如下操作: 在任意位置上插入一个字符: 替换掉任意字符: 删除任意字符. 写一个程序,实现返回最小操作次数,使得对源串 ...

  5. CSS布局之脱离文档流详解——浮动、绝对定位脱离文档流的区别

    1.代码 (1)示例代码1 <!DOCTYPE html> <html lang="zh"> <head> <meta charset=& ...

  6. javascript 内置类型

    JavaScript有七种内置类型: 空类型:null 未定义:undefined 布尔:boolean 数字:number 字符串:string 对象:object 符号:symbol(ES6新增) ...

  7. java 泛型--桥方法

    因为 java 在编译源码时, 会进行 类型擦除, 导致泛型类型被替换限定类型(无限定类型就使用 Object). 因此为保持继承和重载的多态特性, 编译器会生成 桥方法. 本文最后附录所有源码. P ...

  8. Java线程-volatile不能保证原子性

    下面是一共通过volatile实现原子性的例子: 通过建立100个线程,计算number这个变量最后的结果. package com.Sychronized; public class Volatil ...

  9. ubuntu——主题更新,Ubuntu-tweak安装

    1.首先打开终端 2.在终端中输入sudo apt-add-repository ppa:tualatrix/ppa 回车后输入密码等一会,导入密钥 3.再输入sudo apt-get update ...

  10. jquery prop('checked', true)解决attr('checked', true)不能选中radio问题

    正如标题所言,使用:prop('checked', true)就可以了