Linux 进程间通信(三)信号之概述

前言

信号是UNIX/Linux系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动。信号的产生有很多中,比如内存段冲突、系统调用, 浮点处理器错误或者非法指令等;需要强调的是, 信号是在软件层次上对中断的一种模拟,所以通常把它称为是软中断(软中断相对应的是硬件中断, 比如CPU的时钟中断);在诸多Linux进程间通信中, 信号是开销最小的一个。

信号的机制

A给B发送信号,B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号,处理完毕再继续执行。与硬件中断类似——异步模式。但信号是软件层面上实现的中断,早期常被称为“软中断”。
信号的特质:由于信号是通过软件方法实现,其实现手段导致信号有很强的延时性。但对于用户来说,这个延迟时间非常短,不易察觉。
每个进程收到的所有信号,都是由内核负责发送的。也就是说, 我们说的是进程A给进程B发送信号, 其实是进程A先发给内核, 然后由内核再通知进程B。具体流程如下图:

在这里插入图片描述

信号

可以在terminal上执行kill -l 来查看所有的信号。
在这里插入图片描述其中1-31号信号被称为是常规信号(或者是标准信号),34-64 号信号是实时信号, 与驱动编程和硬件相关。

信号的要素

每个信号也有其必备4要素,分别是:

  1. 编号 2. 名称 3. 事件 4. 默认处理动作
    可通过man 7 signal查看官方帮助文档获取。
    Signal       Value          Action        Comment
    ────────────────────────────────────────────
    SIGHUP      1                Term        Hangup detected on controlling terminal or death of controlling process
    SIGINT        2                Term        Interrupt from keyboard
    SIGQUIT     3                 Core        Quit from keyboard
    SIGILL        4                 Core        Illegal Instruction
    SIGFPE       8                Core        Floating point exception
    SIGKILL      9                Term        Kill signal
    SIGSEGV    11              Core        Invalid memory reference
    SIGPIPE      13             Term        Broken pipe: write to pipe with no readers
    SIGALRM    14             Term        Timer signal from alarm(2)
    SIGTERM    15             Term        Termination signal
    SIGUSR1     30,10,16   Term        User-defined signal 1
    SIGUSR2     31,12,17   Term        User-defined signal 2
    SIGCHLD     20,17,18   Ign          Child stopped or terminated
    SIGCONT     19,18,25   Cont        Continue if stopped
    SIGSTOP      17,19,23  Stop        Stop process
    SIGTSTP      18,20,24   Stop        Stop typed at terminal
    SIGTTIN        21,21,26  Stop        Terminal input for background process
    SIGTTOU       22,22,27  Stop        Terminal output for background process

The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
SIGKILL 和SIGSTOP 两个信号只能执行默认动作, 不可以被捕捉、屏蔽、忽略, 这两个信号被称为可靠信号, SIGKILL 默认动作是杀死进程, SIGSTOP默认动作是进程暂停。之所以这么设计是因为, Linux必须保证进程可控, 假如没有这个机制:有一个开机就启动, 且处理了信号动作的黑客进程, 那它就可以无法无天 了,有了SIGKILL和SIGSTOP必须执行默认动作, 那我们就可以直接干掉它。所以Linux保留了最后的强制手段。
在标准信号中,有一些信号是有三个“Value”,第一个值通常对alpha和sparc架构有效,中间值针对x86、arm和其他架构,最后一个应用于mips架构。(所以当我们在使用信号的时候, 为了保证跨平台可移植性,不要用数字, 而是用定义的宏) 一个‘-’表示在对应架构上尚未定义该信号。
不同的操作系统定义了不同的系统信号。因此有些信号出现在Unix系统内,也出现在Linux中,而有的信号出现在FreeBSD或Mac OS中却没有出现在Linux下。这里我们只研究Linux系统中的信号。

大家可能有疑问, 为啥上面的信号似乎漏掉了一些, 这个主要是因为不同的标准,以上是 POSIX.1-1990 规定的,下面是 POSIX.1-2001

       Signal            Value        Action   Comment
       ────────────────────────────────────────────────────────────────────
       SIGBUS      10,7,10         Core    Bus error (bad memory access)
       SIGPOLL                         Term    Pollable event (Sys V).
                                                           Synonym for SIGIO
       SIGPROF     27,27,29     Term    Profiling timer expired
       SIGSYS      12,31,12       Core    Bad system call (SVr4);
                                                            see also seccomp(2)
       SIGTRAP        5               Core    Trace/breakpoint trap

       SIGURG      16,23,21        Ign      Urgent condition on socket (4.2BSD)
       SIGVTALRM   26,26,28    Term    Virtual alarm clock (4.2BSD)
       SIGXCPU     24,24,30      Core    CPU time limit exceeded (4.2BSD);
                                                             see setrlimit(2)
       SIGXFSZ     25,25,31       Core    File size limit exceeded (4.2BSD);
                                                             see setrlimit(2)

 

信号的处理方法

  1. 执行默认动作
  2. 忽略
    1. 不采取任何操作、有两个信号不能被忽略:SIGKILL和SIGSTOP。
  3. 用户捕捉(按照用户的设定来处理)(后面会细讲)
    1. 内核中断正在执行的代码,转去执行先前注册过的处理程序。

默认动作:

Term:终止进程
Ign: 忽略信号 (默认即时对该种信号忽略操作)
Core:终止进程并生成Core文件。(查验进程死亡原因, 用于gdb调试)
Stop:停止进程(这个说法很坑爹, stop咱们翻译过来就是停止, 其实就是暂停)
Cont:继续运行进程。

信号的产生方法

  1. 按键产生。比如: ctrl + c、ctrl + z
  2. 系统调用产生。如: kill、raise、abort
  3. 软件条件产生。如:定时器alarm
  4. 硬件异常产生。如:非法访问内存(段错误SIGSEGV), 内存对齐出错(总线错误),除0操作(SIGFPE)
  5. 命令产生。如:kill 命令

与信号相关的重要概念

信号的一般流程:

递达:递送并且到达进程。(也就是信号从A发出来了, B接收到并且处理了)

未决:产生和递达之间的状态。主要由于阻塞(屏蔽)导致该状态。(也就是信号从A发出来了, B接收到但是没有处理)

阻塞信号集(信号屏蔽字): 将某些信号加入集合,对他们设置屏蔽,当屏蔽x信号后,再收到该信号,该信号的处理将推后(解除屏蔽后)

未决信号集:

1. 信号产生,未决信号集中描述该信号的位立刻翻转为1,表信号处于未决状态。当信号被处理对应位翻转回为0。这一时刻往往非常短暂。

2. 信号产生后由于某些原因(主要是阻塞)不能抵达。这类信号的集合称之为未决信号集。在屏蔽解除前,信号一直处于未决状态。

与信号相关的数据结构

我们知道进程在内核层面上, 内存虚拟为内存四区模型, 在内核区有一个最重要的数据结构:PCB(进程控制块), 落实到数据结构就是task_struct,  在内核眼里,进程就是个task_struct 结构体, 此结构体描述了一个进程几乎所有的信息

 

struct task_struct {
..............
	/* Signal handlers: */
	struct signal_struct		*signal;
	struct sighand_struct		*sighand;
	sigset_t			blocked;
	sigset_t			real_blocked;
	/* Restored if set_restore_sigmask() was used: */
	sigset_t			saved_sigmask;
	struct sigpending		pending;
	unsigned long			sas_ss_sp;
	size_t				sas_ss_size;
	unsigned int			sas_ss_flags;
..............
}


struct signal_struct {
..............

	/* shared signal handling: */
	struct sigpending	shared_pending;
..............
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值