信号机制

信号的概念

信号在我们的生活中随处可见, 如:古代战争中摔杯为号;现代战争中的信号弹;体育比赛中使用的信号枪......它们都有共性:

1. 意图简单 2. 不能携带大量信息(如一个简单的标志位) 3. 满足某个特设条件才发送。

    信号是信息的载体,Linux/UNIX 环境下,古老、经典的通信方式, 现下依然是主要的通信手段。

         Unix早期版本就提供了信号机制,但不可靠,信号可能丢失。Berkeley 和 AT&T都对信号模型做了更改,增加了可靠信号机制。但彼此不兼容。POSIX.1对可靠信号例程进行了标准化。

信号的机制(软中断)

         A给B发送信号,B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号,处理完毕再继续执行。与硬件中断类似——异步模式。但信号是软件层面上实现的中断,早期常被称为“软中断”。

信号的特质:由于信号是通过软件方法实现,其实现手段导致信号有很强的延时性。但对于用户来说,这个延迟时间非常短,不易察觉。

         每个进程收到的所有信号,都是由内核负责发送的,内核处理。

与信号相关的事件和状态

一、产生信号的基本方法:

1. 按键产生,如:Ctrl+c、Ctrl+z、Ctrl+\

2. 系统调用产生,如:kill、raise、abort

3. 软件条件产生,如:定时器alarm

4. 硬件异常产生,如:非法访问内存(段错误)、除0(浮点数例外)、内存对齐出错(总线错误)

5. 命令产生,如:kill命令

二、信号发送的状态:信号产生后,内核会马上把信号进行递送

递达:递送并且到达进程。

阻塞:产生和递达之间的状态。由于某种原因信号未能送达;

未决:产生和递达之间的状态。主要由于阻塞(屏蔽)导致该状态。

三、内核对信号的处理方式有3种:

1. 执行默认动作

  信号的默认处理动作——>有5种处理动作:

           Term:终止进程

           Ignore: 忽略信号 (默认就是对该种信号忽略操作)

           Core:终止进程,生成Core文件。Core文件专门用于调试(查验进程死亡原因,主要用于gdb调试)

           Stop:停止(暂停)进程

           Cont:继续运行进程

2. 忽略(丢弃)

3. 捕捉(调用户处理函数)

         Linux内核的进程控制块PCB是一个结构体,task_struct, 除了包含进程id,状态,工作目录,用户id,组id,文件描述符表,还包含了信号相关的信息,主要指阻塞信号集和未决信号集

注意:阻塞信号集会影响未决信号集

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

未决信号集:

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

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

信号的编号(Linux下支持的信号)

 可以使用kill –l命令查看当前系统可使用的信号有哪些。1-31号常规信号

 1) SIGHUP        2) SIGINT       3) SIGQUIT    4) SIGILL        5) SIGTRAP

 6) SIGABRT      7) SIGBUS      8) SIGFPE       9) SIGKILL      10) SIGUSR1

11) SIGSEGV    12) SIGUSR2    13) SIGPIPE      14) SIGALRM   15) SIGTERM

16) SIGSTKFLT 17) SIGCHLD    18) SIGCONT   19) SIGSTOP    20) SIGTSTP

21) SIGTTIN     22) SIGTTOU   23) SIGURG     24) SIGXCPU    25) SIGXFSZ

26) SIGVTALRM       27) SIGPROF    28) SIGWINCH 29) SIGIO 30) SIGPWR

31) SIGSYS       34) SIGRTMIN 35) SIGRTMIN+1     36) SIGRTMIN+2     37) SIGRTMIN+3

38) SIGRTMIN+4     39) SIGRTMIN+5     40) SIGRTMIN+6     41) SIGRTMIN+7     42) SIGRTMIN+8

43) SIGRTMIN+9     44) SIGRTMIN+10   45) SIGRTMIN+11   46) SIGRTMIN+12   47) SIGRTMIN+13

48) SIGRTMIN+14   49) SIGRTMIN+15   50) SIGRTMAX-14   51) SIGRTMAX-13   52) SIGRTMAX-12

53) SIGRTMAX-11   54) SIGRTMAX-10   55) SIGRTMAX-9     56) SIGRTMAX-8     57) SIGRTMAX-7

58) SIGRTMAX-6     59) SIGRTMAX-5     60) SIGRTMAX-4     61) SIGRTMAX-3     62) SIGRTMAX-2

63) SIGRTMAX-1     64) SIGRTMAX

不存在编号为0的信号。其中1-31号信号称之为常规信号(也叫普通信号或标准信号),34-64称之为实时信号,驱动编程与硬件相关。名字上区别不大。而前32个名字各不相同。

信号4要素

与变量三要素类似的,每个信号也有其必备4要素,分别是:

1. 编号 2. 名称 3. 事件 4. 默认处理动作

可通过man 7 signal查看帮助文档获取。也可查看/usr/src/linux-headers-3.16.0-30/arch/s390/include/uapi/asm/signal.h

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

注:为了平台支持,一个信号可能对应多个值,但是在linux下一般采用中间的信号值

The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.          

在标准信号中,有一些信号是有三个“Value”,第一个值通常对alpha和sparc架构有效,中间值针对x86、arm和其他架构,最后一个应用于mips架构。一个‘-’表示在对应架构上尚未定义该信号。

不同的操作系统定义了不同的系统信号。因此有些信号出现在Unix系统内,也出现在Linux中,而有的信号出现在FreeBSD或Mac OS中却没有出现在Linux下。这里我们只研究Linux系统中的信号。

   注意从man 7 signal帮助文档中可看到 : The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.

   这里特别强调了9) SIGKILL 19) SIGSTOP信号,不允许忽略和捕捉,只能执行默认动作。甚至不能将其设置为阻塞。目的是确保内核可以在极端情况下也可以准确的终止程序

另外需清楚,只有每个信号所对应的事件发生了,该信号才会被递送(但不一定递达),不应乱发信号!!

发布了125 篇原创文章 · 获赞 6 · 访问量 5196

猜你喜欢

转载自blog.csdn.net/weixin_42067873/article/details/102158070
今日推荐