产生一个信号:
- 当用户按某些键时,产生信号
- 硬件异常产生信号:除数为0,无效的存储访问等,这些情况由硬件检测到,将其停止内核,然后内核产生适当的信号通知进程,例如 内核正访问一个无效的存储去的进程会产生一个 SIGSEGV 信号
- 进程使用 kill函数将信号发送给另一个进程
- kill命令发送信号
linux中总共有30中信号:例如
SIGINT : 来自键盘的中断信号(ctrl+c)
SIGKILL: 该信号结束接受信号的进程
SIGTERM:kill命令发出的信号
SIGSTOP:来自键盘(ctrl+z) 或者 调试程序停止执行信号
信号处理:
1.忽略此信号
大多信号按照此方式处理,SIGKILL SIGSTOP这两种信号不能忽略,原因是 他们向超级用户提供一种终止或停止进程的方法
2.执行用户希望的动作,采用signal函数
3.执行系统默认动作,大多数默认动作但是终止该进程
发送信号的函数:
#include<sys/types.h>
#include<signal.h>
int kill(pid_t pid,int signo) //kill函数可以给自己和其他进程发送信号
int raise(int sigano) //raise函数只能给自己进程发信号
alarm
kill中 pid>0 信号发给pid的进程
pid = o发给同组的进程
pid<0 发送给其他进程组id 等于 pid绝对值的进程
pid = -1 发送给所有进程
关于kill 和 killall -9
关于kill 和 killall -9
最近调试一个bug,最后发现竟然是killall name怎么都杀不死进程,换成killall -9 name就好了,读了下面的解释后恍然大悟了。
很多时候,会有人建议你,如果kill杀不掉一个进程,就用kill -9. 为什么?
kill是Linux下常见的命令。其man手册的功能定义如下:
kill – send a signal to a process
明朗了,其实kill就是给某个进程id发送了一个信号。默认发送的信号是SIGTERM,而kill -9发送的信号是SIGKILL,即exit。exit信号不会被系统阻塞,所以kill -9能顺利杀掉进程。当然你也可以使用kill发送其他信号给进程。
killall – kill processes by name
即,通过指定进程名的方式杀死进程。
kill -9 pid
killall -9 进程名字
例如kill -9 6745 等同于 killall -9 siganl
#include<unistd.h>
unsigned int alarm(unsigned int seconds)
经过seconds秒后会产生SIGALRM信号,如果不捕捉此信号,默认终止该进程
#include<unistd.h>
int pause(void)
pause函数是 使进程挂起直至捕捉到新一个信号,否则一直阻塞
信号处理函数:
#include<signal.h>
void (*signal (int signo, void(*func)(int))) (int)
signal函数是一个函数指针
其中,SIG_IGN: 忽略此信号
SIG_DFL:按照默认处理
信号处理函数名:使用该函数处理
例子:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void my_func(int sign_no)
{
if(SIGINT == sign_no)
printf(“i have got SIGINT \n”);
else if(SIGQUIT == sign_no)
printf(“i have got SIGQUIT \n”);
}
int main()
{
printf(“waiting for signal SIGINT OR SIGQUIT \n”);
/* 注册信号处理函数 */
signal(SIGINT,my_func);
signal(SIGQUIT,my_func);
pause();
exit(0);
}
通过ps aux 找到./signal的pid号
在另一个用kill -s SIGINT pid号 来产生一个SIGINT信号
运行结果:
./signal
waiting for signal SIGINT OR SIGQUIT
^Ci have got SIGINT