赞
踩
信号(Signals)是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。Linux信号是Linux进程间通信机制中唯一的异步通信机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。
一般情况下,linux信号的来源可分为以下三种:
1.硬件方式:除数为零、无效的存储访问等硬件异常产生信号。这些事件通常由硬件(如:CPU)检测到,并将其通知给Linux操作系统内核,然后内核生成相应的信号,并把信号发送给该事件发生时正在进行的程序。
2.软件方式:用户在终端下调用kill命令向进程发送任务信号、进程调用kill或sigqueue函数发送信号、当检测到某种软件条件已经具备时发出信号,如由alarm或settimer设置的定时器超时时将生成SIGALRM信号等多种情景均可产生信号。
3.键盘输入:当用户在终端上按下某键时,将产生信号。如按下组合键Ctrl+C将产生一个SIGINT信号,Ctrl+\产生一个SIGQUIT信号等。
我们可运行kill -l查看Linux支持的信号列表:
sl@Li:~/Works$ 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 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
可以看到Linux中系统一共支持64种信号,其中1到31号信号为普通信号(也程为不可靠信号),34到64为实时信号(可靠信号)。可靠信号与不可靠信号的区别:
这里的不可靠主要是不支持信号队列,就是当多个信号发生在进程中的时候(收到信号的速度超过进程处理的速度的时候),这些没来的及处理的信号就会被丢掉,仅仅留下一个信号。
可靠信号是多个信号发送到进程的时候(收到信号的速度超过进程处理信号的速度的时候),这些没来的及处理的信号就会排入进程的队列。等进程有机会来处理的时候,依次再处理,信号不丢失。
下面列出几个常用的信号:
SIGHUP:
当用户退出终端时,由该终端开启的所有进程都退接收到这个信号,默认动作为终止进程。
SIGINT:
程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl+C)时发出,用于通知前台进程组终止进程。
SIGQUIT:
和SIGINT类似, 但由QUIT字符(通常是Ctrl+\)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。
SIGKILL:
用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略。
SIGTERM:
程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出。
SIGSTOP:
停止(stopped)进程的执行. 注意它和terminate以及interrupt的区别:该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略。
代码示例:
下面的代码收到程序退出信号后会执行用户定义的信号处理函数来替代系统默认的处理程序。
#include
#include
#include
#include
#include
void sig_handle(int sig) {
printf("received signal: %d, quit.\n", sig);
exit(0);
}
int main () {
signal(SIGINT, sig_handle);
signal(SIGKILL, sig_handle);
signal(SIGSEGV, sig_handle);
signal(SIGTERM, sig_handle);
int i = 0;
while (1) {
printf("%d\n", ++i);
sleep(2);
}
printf("main quit.");
return 0;
}
运行结果:
received signal: 15, quit.
实际上,Linux信号可以看作是异步通知,通知接收信号的进程有哪些事情发生了,也可以简单理解为信号是某种形式上的软中断。想要深入了解Linux信号的运行机制,可以参考本站的Linux教程中给出的资料,结合自己在Linux系统上的实践操作得出自己的结论。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。