UNIX 信号基本概念
2014-04-07 10:31
246 查看
1. 信号的基本概念
为了理解信号,先从我们最熟悉的场景说起:用户输入命令,在Shell下启动一个前台进程。
用户按下Ctrl-C,这个键盘输入产生一个硬件中断。
如果CPU当前正在执行这个进程的代码,则该进程的用户空间代码暂停执行,CPU从用户态切换到内核态处理硬件中断。
终端驱动程序将Ctrl-C解释成一个
SIGINT信号,记在该进程的PCB中(也可以说发送了一个
SIGINT信号给该进程)。
当某个时刻要从内核返回到该进程的用户空间代码继续执行之前,首先处理PCB中记录的信号,发现有一个
SIGINT信号待处理,而这个信号的默认处理动作是终止进程,所以直接终止进程而不再返回它的用户空间代码执行。
注意,Ctrl-C产生的信号只能发给前台进程。我们看到一个命令后面加个
&可以放到后台运行,这样Shell不必等待进程结束就可以接受新的命令,启动新的进程。Shell可以同时运行一个前台进程和任意多个后台进程,只有前台进程才能接到像Ctrl-C这种控制键产生的信号。前台进程在运行过程中用户随时可能按下Ctrl-C而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到
SIGINT信号而终止,所以信号相对于进程的控制流程来说是异步(Asynchronous)的。
用
kill -l命令可以察看系统定义的信号列表,
$ kill -l 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 ...
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
每个信号都有一个编号和一个宏定义名称,这些宏定义可以在
signal.h中找到,例如其中有定义
#define SIGINT 2。
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 ...
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
上表中第一列是各信号的宏定义名称,第二列是各信号的编号,第三列是默认处理动作,
Term表示终止当前进程,
Core表示终止当前进程并且Core Dump(下一节详细介绍什么是Core Dump),
Ign表示忽略该信号,
Stop表示停止当前进程,
Cont表示继续执行先前停止的进程,表中最后一列是简要介绍,说明什么条件下产生该信号。
产生信号的条件主要有:
用户在终端按下某些键时,终端驱动程序会发送信号给前台进程,例如Ctrl-C产生
SIGINT信号,Ctrl-\产生
SIGQUIT信号,Ctrl-Z产生
SIGTSTP信号(可使前台进程停止)。
硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为
SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,,MMU会产生异常,内核将这个异常解释为
SIGSEGV信号发送给进程。
一个进程调用
kill(2)函数可以发送信号给另一个进程。
可以用
kill(1)命令发送信号给某个进程,
kill(1)命令也是调用
kill(2)函数实现的,如果不明确指定信号则发送
SIGTERM信号,该信号的默认处理动作是终止进程。
当内核检测到某种软件条件发生时也可以通过信号通知进程,例如闹钟超时产生
SIGALRM信号,向读端已关闭的管道写数据时产生
SIGPIPE信号。
如果不想按默认动作处理信号,用户程序可以调用
sigaction(2)函数告诉内核如何处理某种信号(
sigaction函数稍后详细介绍),可选的处理动作有以下三种:
忽略此信号。
执行该信号的默认处理动作。
提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉(Catch)一个信号。
相关文章推荐
- UNIX/LINUX信号基本概念释疑
- 信号完整性分析系列——1基本概念
- linux信号基本概念及如何产生信号
- 【SCOM前期-基本概念】SCOM检测信号简介
- 信号(一)基本概念
- linux中信号的基本概念
- 高级Unix编程-基本概念
- Unix/Linux C++应用开发-C++基本概念“常量”
- linux系统编程手册阅读笔记-c20:信号的基本概念
- 空时频信号处理基本概念
- 【Linux】信号的基本概念
- 信号的基本概念
- 信号处理的基本概念
- 基本概念学习(2001)---控制信号、时序信号
- 信号------信号的基本概念
- Linux信号的基本概念
- android平台上GPS信号的获取和展示(一)之概念与基本类
- 关于信号处理的一些基本概念
- Unix中存储管理的一些基本概念
- 信号的基本概念