对信号一直感到很神秘,好像是能够hack的地方,呵呵...
看了看书,感觉其实信号不过是一种类似中断处理机制,
书上说信号是进程(系统进程和用户进程)间通信的方法。在
进程收到信号时,其执行的流程将被系统中断,如经常使用的
Ctrl+C(中断),系统将退出程序。
例如:
divzero.c:
main()
{
int a,b;
scanf("%d %d", &a, &b);
printf("a/b is %d",a/b);
}
如果用3 0来运行的话,系统输入了 “浮点数例外" 的提示。
signal.c:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void signal_handler(int signal) {
printf("Caught signal %d\n", signal);
if (SIGTSTP == signal) //Ctrl+Z(Terminal strp)
{
printf("SIGTSTP (Ctrl+Z)\n");
}
else if (SIGQUIT == signal)
{
printf("SIGQUIT (QUIT)\n");
}
else if (SIGUSR1 == signal)
{
printf("SIGSR1 \n");
}
else if (SIGUSR2 == signal)
{
printf("SIGSR2 \n");
}
}
void sigint_handler(int x) { //中断信号处理函数
printf("Caught a Ctrl + C(SIGINT) in a handler\nExiting\n");
exit(0);
}
int
main (int argc, char *argv[])
{
signal(SIGQUIT, sigint_handler); //注册信号处理函数
signal(SIGTSTP, signal_handler);
signal(SIGUSR1, signal_handler);
signal(SIGUSR2, signal_handler);
signal(SIGINT, sigint_handler);
while (1) //死循环
{
;
}
return 0;
}
如果运行时按下Ctrl+C发送一个中断信号,那么出现
^CCaught a Ctrl + C(SIGINT) in a handler
Exiting
程序结束。
此外使用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
也能通过他发送信号给进程:kill -numberofsignal pid
如果使用strace -p pid就能不停的跟踪进程获得的信号,如运行signal.c:
使用strace 命令:
两次Ctrl+Z后结束 在另一个终端:
Process 6825 attached - interrupt to quit
--- SIGTSTP (Stopped) @ 0 (0) ---
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77f4000
write(1, "Caught signal 20\n", 17) = 17
write(1, "SIGTSTP (Ctrl+Z)\n", 17) = 17
sigreturn() = ? (mask now [])
--- SIGTSTP (Stopped) @ 0 (0) ---
write(1, "Caught signal 20\n", 17) = 17
write(1, "SIGTSTP (Ctrl+Z)\n", 17) = 17
sigreturn() = ? (mask now [])
write(1, "Caught a Ctrl + C(SIGINT) in a h"..., 39) = 39
write(1, "Exiting\n", 8) = 8
exit_group(0) = ?
Process 6825 detached
可见strace的强大之处,呵呵...
再如处理一个除数为0的中断:
ZeroInterrupt.c:
#include <signal.h>
void signal_handler (int signal) {
printf("Something wrong with your program!\n");
if (signal == SIGFPE) //SIGFPE为算术错误信号
{
printf("fate error happen!\n");
}
exit(0);
}
int
main (int argc, char *argv[])
{
signal(SIGFPE, signal_handler); //注册信号处理函数
int i;
for (i = -10; i <=10 ; i++) {
printf("%d div %d is %d\n", i , i , i/i);
}
return 0;
}
运行如下:
-10 div -10 is 1
-9 div -9 is 1
-8 div -8 is 1
-7 div -7 is 1
-6 div -6 is 1
-5 div -5 is 1
-4 div -4 is 1
-3 div -3 is 1
-2 div -2 is 1
-1 div -1 is 1
Something wrong with your program!
fate error happen!
看来信号的设计是为了处理一些通用系统(硬件)的问题,来处理编程中的硬伤。
看了看书,感觉其实信号不过是一种类似中断处理机制,
书上说信号是进程(系统进程和用户进程)间通信的方法。在
进程收到信号时,其执行的流程将被系统中断,如经常使用的
Ctrl+C(中断),系统将退出程序。
例如:
divzero.c:
main()
{
int a,b;
scanf("%d %d", &a, &b);
printf("a/b is %d",a/b);
}
如果用3 0来运行的话,系统输入了 “浮点数例外" 的提示。
signal.c:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void signal_handler(int signal) {
printf("Caught signal %d\n", signal);
if (SIGTSTP == signal) //Ctrl+Z(Terminal strp)
{
printf("SIGTSTP (Ctrl+Z)\n");
}
else if (SIGQUIT == signal)
{
printf("SIGQUIT (QUIT)\n");
}
else if (SIGUSR1 == signal)
{
printf("SIGSR1 \n");
}
else if (SIGUSR2 == signal)
{
printf("SIGSR2 \n");
}
}
void sigint_handler(int x) { //中断信号处理函数
printf("Caught a Ctrl + C(SIGINT) in a handler\nExiting\n");
exit(0);
}
int
main (int argc, char *argv[])
{
signal(SIGQUIT, sigint_handler); //注册信号处理函数
signal(SIGTSTP, signal_handler);
signal(SIGUSR1, signal_handler);
signal(SIGUSR2, signal_handler);
signal(SIGINT, sigint_handler);
while (1) //死循环
{
;
}
return 0;
}
如果运行时按下Ctrl+C发送一个中断信号,那么出现
^CCaught a Ctrl + C(SIGINT) in a handler
Exiting
程序结束。
此外使用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
也能通过他发送信号给进程:kill -numberofsignal pid
如果使用strace -p pid就能不停的跟踪进程获得的信号,如运行signal.c:
使用strace 命令:
两次Ctrl+Z后结束 在另一个终端:
Process 6825 attached - interrupt to quit
--- SIGTSTP (Stopped) @ 0 (0) ---
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77f4000
write(1, "Caught signal 20\n", 17) = 17
write(1, "SIGTSTP (Ctrl+Z)\n", 17) = 17
sigreturn() = ? (mask now [])
--- SIGTSTP (Stopped) @ 0 (0) ---
write(1, "Caught signal 20\n", 17) = 17
write(1, "SIGTSTP (Ctrl+Z)\n", 17) = 17
sigreturn() = ? (mask now [])
write(1, "Caught a Ctrl + C(SIGINT) in a h"..., 39) = 39
write(1, "Exiting\n", 8) = 8
exit_group(0) = ?
Process 6825 detached
可见strace的强大之处,呵呵...
再如处理一个除数为0的中断:
ZeroInterrupt.c:
#include <signal.h>
void signal_handler (int signal) {
printf("Something wrong with your program!\n");
if (signal == SIGFPE) //SIGFPE为算术错误信号
{
printf("fate error happen!\n");
}
exit(0);
}
int
main (int argc, char *argv[])
{
signal(SIGFPE, signal_handler); //注册信号处理函数
int i;
for (i = -10; i <=10 ; i++) {
printf("%d div %d is %d\n", i , i , i/i);
}
return 0;
}
运行如下:
-10 div -10 is 1
-9 div -9 is 1
-8 div -8 is 1
-7 div -7 is 1
-6 div -6 is 1
-5 div -5 is 1
-4 div -4 is 1
-3 div -3 is 1
-2 div -2 is 1
-1 div -1 is 1
Something wrong with your program!
fate error happen!
看来信号的设计是为了处理一些通用系统(硬件)的问题,来处理编程中的硬伤。