您的位置:首页 > 其它

信号------信号的基本概念

2017-04-16 13:58 218 查看
1.linux信号

为了理解信号,先从我们最熟悉的场景说起:

⽤用户输⼊入命令,在Shell下启动⼀一个前台进程;

⽤用户按下Ctrl-C,这个键盘输⼊入产⽣生⼀一个硬件中断;

如果CPU当前正在执⾏行这个进程的代码,则该进程的⽤用户空间代码暂停执⾏行,CPU从⽤户态 切换到内核态处理硬件中断;

终端驱动程序将Ctrl-C解释成⼀一个SIGINT信号,记在该进程的PCB中(也可以说发送了⼀一 个SIGINT信号给该进程)。

linux中共有62个信号,我们可以通过kill -l命令来进行查询全部信号



1~31的信号是普通信号;

34~64的信号为实时信号(即时发送,即时响应);

我们接下来学习的是普通信号

2.前台进程/后台进程

进程的默认情况都是在前台运行,用户可以通过终端按键像ctrl -c来终止进程;此时不能再向shell输入命令,因为此时shell在后台运行



将前台进程转换到后台的方法是加上一个&符号(./proc &),此时在运行proc进程的时候任然可以向shell输入命令并且可以执行。要想中断程序,此时ctrl -c不能终端程序了,我们有两种终止的办法

第一种,将该后台程序转换为前台进程并且ctrl -c终止掉;

第二种,利用ps aux|grep ‘proc’查看该程序的id,通过kill -9 id号来杀死该进程;

shell可以同时运行一个前台程序和多个后台程序,只有前台进程才能接受控制按键产生的信号

3.每一个信号都有一个编号和一个宏定义的名称,例如:#define SIGINT 2



4.内核处理某种信号可选的处理动作有三种:

忽略此信号(忽略)

执行该信号的默认处理动作

提供一个信号处理函数,要求内核在处理信号时切换到用户态执行处理这个函数,捕捉一个信号(自定义捕捉信号)

通过命令man 7 signal可以查看信号的默认处理动作,如下:



5.如果不想按照默认处理动作来处理信号,我们可以通过signal和sigaction函数来对信号自定义捕捉



参数signum为信号编号,handler为一个函数指针,对信号的处理动作的自定义





sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。

他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该使用这个接口)

给信号signum设置新的信号处理函数act, 同时保留该信号原有的信号处理函数oldact

int sigaction(int signo,const struct sigaction *restrict act,

struct sigaction *restrict oact);

结构sigaction定义如下:

struct sigaction{

void (*sa_handler)(int);

sigset_t sa_mask;

int sa_flag;

void (sa_sigaction)(int,siginfo_t ,void *);

};

参数:

sa_handler字段包含一个信号捕捉函数的地址

sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加进进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值。

sa_flag是一个选项,主要理解两个

SA_INTERRUPT 由此信号中断的系统调用不会自动重启

SA_RESTART 由此信号中断的系统调用会自动重启

SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针

最后一个参数是一个替代的信号处理程序,当设置SA_SIGINFO时才会用他。

6.对于8号信号,SIGFPE(除0时会产生该信号)可以通过上面的信号默认动作的查看,知道该信号会会终止该程序并产生一个core dump文件,在下一个主题—信号的产生时我们将介绍什么是core dump文件,并如何使用;

7.SIGKILL信号(9号信号)是不能够自定义捕捉的;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息