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

有以下主题:

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

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

    一次在源码里看到 %*s 的格式,从未见过百思不得其解,今天用google的code搜索,搜到一些使用范例,猜测%*s 是说这里有一些字符,长度不一定,按正则表达式的习惯,*代办任意非负整数.例如: ...

  2. 在 Windows 上快速安装并运行 Laravel 5.x

    安装 PHP 注意一:Laravel 5.0 开始对 PHP 版本的要求是 >=5.4,Laravel 5.1 要求 PHP 版本>=5.5.9,所以,建议大家尽量安装 5.5.x 的最新 ...

  3. c语言打印uint64, int64

    http://stackoverflow.com/questions/9225567/how-to-print-a-int64-t-type-in-c

  4. [88221008]调用新下单接口失败,result:162020004,resInfo

    [88221008]调用新下单接口失败,result:162020004,resInfo

  5. Tags Used In OpenERP 7.0

    In OpenERP 7.0. the form view of each object has been redesigned so that the object the user is work ...

  6. sql存储过程等-版本控制

    数据库开发人员总在想,每次修改了函数/存储过程,我们都得自己做备份,用以历史参考,当发现错误的时候,可以回滚 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON ...

  7. linux 挂载 ISO 文件

    sudo sudo mount -o loop SUSE-Linux-10.1-GM-DVD-x86_64.iso /media/cdrom/ sudo umount /media/cdrom

  8. 【python下使用OpenCV实现计算机视觉读书笔记1】输入输出

    说明: 该部分内容为<OpenCV Computer Vision with Python>读书笔记. 1.读入文件与保存. import cv2 image=cv2.imread('a. ...

  9. Django的ORM中如何判断查询结果是否为空,判断django中的orm为空

    result= Booking.objects.filter() #方法一 .exists() if result.exists(): print "QuerySet has Data&qu ...

  10. 点滴积累【JS】---JS实现动画闪烁效果

    效果: 思路:首先获得图片数组,然后做JS定时用setTimeout和setInterval在用显示隐藏实现闪烁效果. 代码: <!DOCTYPE html PUBLIC "-//W3 ...