1、信号的基本概念
进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。进程通过系统调用signal来指定进程对某个信号的处理行为。
2、信号本质是int型数字编号(事先定义好的)
解释:信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据(比如文字,语音等数据),他是内核事先定义好的int数字,调用signal函数时,来指定信号内型。
3、谁发出的信号
(1)用户在ubuntu终端(终端就是一个前台运行的进程)按下按键比如ctrl+C等
(2)硬件异常后,操作系统内核发送信号
(3)用户使用kill命令(是一个内核提供的API函数)比如用:kill - 9 xxx
(4)某种软件条件满足后也会发送信号,如alarm闹钟时间到会产生SIGALARM信号、向一个读端已近关闭的管道write时,会产生SIGPIPE
4、信号由谁处理,处理方式
(1)捕获信号,进程可以指定处理函数,由该函数来处理。
(2)忽略信号,对该信号不做任何处理,就象未发生过一样。
(3)默认处理,这种缺省操作,对大部分的信号的缺省操作是使得进程终止。
5、每个int型的信号值发生的原因(这里列出常见的几种)
5.1在linux下/usr/include/i386-linux-gnu/bits 下的signum.h定义了所以的信号值
信号 值 处理动作 发出信号的原因
SIGHUP 1 A 终端挂起或者控制进程终止
SIGINT 2 A 键盘中断(如break键被按下) 正常终止
SIGQUIT 3 C 键盘的退出键被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)发出的退出指令,异常终止
SIGIO 23,29,22 A 某I/O操作现在可以进行了(4.2 BSD)
SIGKILL 9 AEF 杀死进程的终极方法
SIGSEGV 11 C 无效的内存引用
SIGPIPE 13 A 管道破裂: 写一个没有读端口的管道
SIGALRM 14 A 由alarm(2)发出的信号
SIGTERM 15 A 终止信号
SIGUSR1 30,10,16 A 用户自定义信号1 给用户做进程间通信,不像其他的处理方法被绑定了
SIGUSR2 31,12,17 A 用户自定义信号2
SIGCHLD 20,17,18 B 子进程结束信号
SIGCONT 19,18,25 进程继续(曾被停止的进程)
SIGSTOP 17,19,23 DEF 终止进程
SIGTSTP 18,20,24 D 控制终端(tty)上按下停止键
SIGTTIN 21,21,26 D 后台进程企图从控制终端读
SIGTTOU 22,22,27 D 后台进程企图从控制终端写
5.2处理动作一项中的字母含义如下
A 缺省的动作是终止进程B 缺省的动作是忽略此信号
C 缺省的动作是终止进程并进行内核映像转储(dump core)
D 缺省的动作是停止进程
E 信号不能被捕获
F 信号不能被忽略
6、进程对信号的处理实例
6.1、signal系统调用
sighandler_t signal( int signum, sighandler_t handler );
SIG_IGN:忽略参数signum所指的信号。
SIG_DFL:恢复参数signum所指信号的处理方法为默认值。
一、signal函数绑定一个捕获函数后信号发生后会自动执行绑定的捕获函数,并且把信号编号作为传参传给捕获函数
二、signal的返回值在出错时为SIG_ERR,绑定成功时返回旧的捕获函数
6.2、signal代码示例
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
typedef void (*sighandler_t)(int); //下面使用内核用sighandler_t定义的SIG_DFL,需要声明一下
void func(int sig)
{
if (SIGINT != sig)
return 0;
printf("func for signal: %d.\n", sig);
}
int main(void)
{
sighandler_t ret = (sighandler_t)(-2); //
//signal(SIGINT, func) ;
//signal(SIGINT, SIG_DFL); // 指定信号SIGINT为默认处理
ret = signal(SIGINT, SIG_IGN); // 指定信号SIGINT为忽略处理
if (SIG_ERR == ret)
{
perror("signal:");
exit(-1);
}
printf("before while(1)\n");
while(1);
printf("after while(1)\n");
return 0;
}