三者都是结束/终止进程运行。
1.SIGINT SIGTERM区别
前者与字符ctrl+c关联,后者没有任何控制字符关联。
前者只能结束前台进程,后者则不是。
2.SIGTERM SIGKILL的区别
前者可以被阻塞、处理和忽略,但是后者不可以。KILL命令的默认不带参数发送的信号就是SIGTERM.让程序有好的退出。因为它可以被阻塞,所以有的进程不能被结束时,用kill发送后者信号,即可。即:kill -9 进程号。
http://www.mirecle.com/2010/05/20/sigterm-sigint-sigkill-difference.html
我看网上应该有不少搜索这个区别的问题,但是回答的都不全面,其中sigterm与sigint尤其有一点区别比较重要,但大都没有提及,今天我就遇到了这个问题,纠结了20分钟才搞明白咋回事。
首先,对于说这几个信号都是终止程序运行的说法不太准确,因为程序收到信号后,如果不对信号处理,就会导致程序退出,但如果程序捕获信号进行处理,按照它的逻辑,它是不一定会退出的。
在这三个信号中,sigkill是不能被捕获的,程序收到这个信号后,一定会退出。这就是kill -9一定能保证将程序杀死的原因。
下面说一下sigterm与sigint的区别,其中有一点区别区别很多文章都没有提及,也是我写这篇blog的原因(如果人家都写了,我就不用写了呗)
信号 |
产生方式 |
对进程的影响 |
sigint |
通过ctrl+c将会对当进程发送此信号 |
信号被当前进程树接收到,也就是说,不仅当前进程会收到信号,它的子进程也会收到 |
sigterm |
kill命令不加参数就是发送这个信号 |
只有当前进程收到信号,子进程不会收到。如果当前进程被kill了,那么它的子进程的父进程将会是init,也就是pid为1的进程 |
下面这两个代码片段就能够验证这种情况(注意使用pcntl的时候,一定要declare ticks,要不然会杯具的发现函数没有被调用,进程不退出,信号发过去没有作用。php手册竟然没有强调这一点):
文件:loadhelper.php
04 |
$arr_processes = array (); |
06 |
function terminate( $signo ){ |
10 |
pcntl_signal(SIGTERM, "terminate" , true); |
11 |
pcntl_signal(SIGINT, "terminate" , true); |
13 |
foreach ( $argv as $key => $operation ){ |
20 |
$process = proc_open( $operation , array (), & $pipes ); |
21 |
if (false === $process ){ |
24 |
$arr_processes [] = $process ; |
文件:child.php
03 |
pcntl_signal(SIGINT, "terminate" ); |
04 |
pcntl_signal(SIGTERM, "terminate" ); |
06 |
function terminate( $signo ){ |
使用命令php loadhelper.php “php test.php”可以启动这个测试。
1.输入ctrl+c发送sigint可以看到,父进程与子进程的terminate都得到了执行,都有输出,但父进程不会退出,因为子进程还没有退出
2.通过kill向父进程的pid发送sigterm,可以看到,只有父进程输出
遗留问题:
父进程(loadhelper)接受到一次信号后,如果在terminate函数中调用exit,它还是不能退出的,因为还有子进程没有退出。但是
从此以后它就不能再接收信号了(子进程还是能够接收到sigint),可能是exit使进程进入了待回收状态,具体还 需要后续在分析一把。
1. SIGQUIT:
On POSIX-compliant platforms, SIGQUIT is the
signal sent to a process by its controlling terminal when the user
requests that the process perform a core dump. SIGQUIT can usually be
induced with Control-\. On Linux, one may also use Ctrl-4 or, on the
virtual console, the SysRq key.
2. SIGTERM:
SIGTERM
is the default signal sent to a process by the kill or killall
commands. It causes the termination of a process, but unlike the SIGKILL
signal, it can be caught and interpreted (or ignored) by the process.
Therefore, SIGTERM is akin to asking a process to terminate nicely,
allowing cleanup and closure of files. For this reason, on many Unix
systems during shutdown, init issues SIGTERM to all processes that are
not essential to powering off, waits a few seconds, and then issues
SIGKILL to forcibly terminate any such processes that remain.
3. SIGINT:
On POSIX-compliant platforms, SIGINT is the signal sent to a process by
its controlling terminal when a user wishes to interrupt the process.
SIGINT is sent when the user on the process' controlling terminal
presses the interrupt the running process key — typically Control-C, but
on some systems, the "delete" character or "break" key.
4. SIGKILL:
On POSIX-compliant platforms, SIGKILL is the signal sent to a process
to cause it to terminate immediately. When sent to a program, SIGKILL
causes it to terminate immediately. In contrast to SIGTERM and SIGINT,
this signal cannot be caught or ignored, and the receiving process
cannot perform any clean-up upon receiving this signal.
SIGHUP 终止进程 终端线路挂断
SIGINT 终止进程 中断进程
SIGQUIT 建立CORE文件终止进程,并且生成core文件
SIGILL 建立CORE文件 非法指令
SIGTRAP 建立CORE文件 跟踪自陷
SIGBUS 建立CORE文件 总线错误
SIGSEGV 建立CORE文件 段非法错误
SIGFPE 建立CORE文件 浮点异常
SIGIOT 建立CORE文件 执行I/O自陷
SIGKILL 终止进程 杀死进程
SIGPIPE 终止进程 向一个没有读进程的管道写数据
SIGALARM 终止进程 计时器到时
SIGTERM 终止进程 软件终止信号
SIGSTOP 停止进程 非终端来的停止信号
SIGTSTP 停止进程 终端来的停止信号
SIGCONT 忽略信号 继续执行一个停止的进程
SIGURG 忽略信号 I/O紧急信号
SIGIO 忽略信号 描述符上可以进行I/O
SIGCHLD 忽略信号 当子进程停止或退出时通知父进程
SIGTTOU 停止进程 后台进程写终端
SIGTTIN 停止进程 后台进程读终端
SIGXGPU 终止进程 CPU时限超时
SIGXFSZ 终止进程 文件长度过长
SIGWINCH 忽略信号 窗口大小发生变化
SIGPROF 终止进程 统计分布图用计时器到时
SIGUSR1 终止进程 用户定义信号1
SIGUSR2 终止进程 用户定义信号2
SIGVTALRM 终止进程 虚拟计时器到时
1) SIGHUP 本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控
制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端
不再关联.
2) SIGINT 程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出
3) SIGQUIT 和SIGINT类似, 但由QUIT字符(通常是Ctrl-)来控制. 进程在因收到
SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信
号.
4) SIGILL 执行了非法指令. 通常是因为可执行文件本身出现错误, 或者试图执行
数据段. 堆栈溢出时也有可能产生这个信号.
5) SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用.
6) SIGABRT 程序自己发现错误并调用abort时产生.
6) SIGIOT 在PDP-11上由iot指令产生, 在其它机器上和SIGABRT一样.
7) SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长
的整数, 但其地址不是4的倍数.
8) SIGFPE 在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢
出及除数为0等其它所有的算术的错误.
9) SIGKILL 用来立即结束程序的运行. 本信号不能被阻塞, 处理和忽略.
10) SIGUSR1 留给用户使用
11) SIGSEGV 试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据.
12) SIGUSR2 留给用户使用
13) SIGPIPE Broken pipe
14) SIGALRM 时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该
信号.
15) SIGTERM 程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和
处理. 通常用来要求程序自己正常退出. shell命令kill缺省产生这
个信号.
17) SIGCHLD 子进程结束时, 父进程会收到这个信号.
18) SIGCONT 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞. 可以用
一个handler来让程序在由stopped状态变为继续执行时完成特定的
工作. 例如, 重新显示提示符
19) SIGSTOP 停止(stopped)进程的执行. 注意它和terminate以及interrupt的区别:
该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略.
20) SIGTSTP 停止进程的运行, 但该信号可以被处理和忽略. 用户键入SUSP字符时
(通常是Ctrl-Z)发出这个信号
21) SIGTTIN 当后台作业要从用户终端读数据时, 该作业中的所有进程会收到SIGTTIN
信号. 缺省时这些进程会停止执行.
22) SIGTTOU 类似于SIGTTIN, 但在写终端(或修改终端模式)时收到.
23) SIGURG 有"紧急"数据或out-of-band数据到达socket时产生.
24) SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/
改变
25) SIGXFSZ 超过文件大小资源限制.
26) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.
27) SIGPROF 类似于SIGALRM/SIGVTALRM, 但包括该进程用的CPU时间以及系统调用的
时间.
28) SIGWINCH 窗口大小改变时发出.
29) SIGIO 文件描述符准备就绪, 可以开始进行输入/输出操作.
30) SIGPWR Power failure
有
两个信号可以停止进程:SIGTERM和SIGKILL。
SIGTERM比较友好,进程能捕捉这个信号,根据您的需要来关闭程序。在关闭程序之前,您可以结束打开的记录文件和完成正在做的任务。在某些情况下,假
如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号。
对于SIGKILL信号,进程是不能忽略的。这是一个 “我不管您在做什么,立刻停止”的信号。假如您发送SIGKILL信号给进程,Linux就将进程停止在那里。