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

有以下主题:

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

起始信号的概念还是挺简单的,但是没有写过代码练习这块的内容。不知道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. laravel5.1安装

    Laravel 于6月9日正式发布了 5.1 最新 LTS 版本.这是 Laravel 历史上第一个提供 LTS(长期支持 - long-time support) 支持的版本. 首先使用Larave ...

  2. Thinkphp学习笔记-模板赋值

    如果要在模板中输出变量,必须在在控制器中把变量传递给模板,系统提供了assign方法对模板变量赋值,无论何种变量类型都统一使用assign赋值. $this->assign('name',$va ...

  3. 使用Loader实时查询本地数据库用法

    在看Android的文档时,看到了这么一个东西: Loader 究竟是什么东西呢? Introduced in Android 3.0, loaders make it easy to asynchr ...

  4. C#基础视频教程7.2 如何编写简单游戏

    前面一小节我们实现了简单的碰撞检测,但是实际上游戏的对象并不是一个标准的矩形(小鸟是一个不规则的物体,其实碰撞的管道也是不规则物体),所以如果真的要做的比较完美,我们自己要写一个方法,能够导入一个图像 ...

  5. PHPNOW如何添加虚拟主机

    1 打开PHPNow控制面板,输入0,点回车 2 新增主机名称(你可以输入127.0.0.2到127.0.0.255),点击回车之后要求输入主机别名,不要写,直接回车,再要求输入网站目录,也不选,再回 ...

  6. PHP FTP函数

    PHP FTP 函数 PHP FTP 简介 FTP 函数通过文件传输协议 (FTP) 提供对文件服务器的客户端访问. FTP 函数用于打开.登录以及关闭连接,同时用于上传.下载.重命名.删除及获取文件 ...

  7. 记一发Hive on tez的配置(Hive 3.1.1, Hadoop 3.0.3, Tez 0.9.1)

    直接下载Tez的binary包部署安装是有问题的,因为默认支持hadoop版本为2.7,2.7以上的就需要手动编译了. 下载Tez源码 CD到源码文件夹,mvn install -Dhadoop.ve ...

  8. 算法笔记_142:无向图的欧拉回路求解(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 John's trip Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8 ...

  9. C# 通过form表单下载文本文件

    public void DownLoadConfigFile(string name) { //获取文件字符串内容 var data = _service.ReadFileStr(_configure ...

  10. Spring @Autowired、@Resource、@Required、@Component、@Repository、@Service、@Controller注解的用法和作用

    Spring @Autowired,@Resource,@Required注解的用法和作用 Spring中 @Autowired标签与 @Resource标签 的区别 Spring注解@Compone ...