1 What are signals and how are they used
1.当进程接收到信号,进程会暂停,来处理信号
1.1 How we use signals
1.killall cat
杀死所有的cat程序
2.信号源与信号
信号源 | 信号 |
---|---|
kill | SIGTERM |
Ctrl-c | SIGINT |
Ctrl-z | SIGTSTP |
fg | SIGCONT |
2 The Wide World of Signals
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 |
SIGABRT | 6 | Core | Abort signal from abort(3) |
SIGFPE | 8 | Core | Floating point exception |
SIGKILL | 9 | Term | Kill signal |
SIGSEGV | 11 | Core | Invalid memory reference |
SIGPIPE | 13 | Term | Broken pipe: write to pipe with no readers |
SIGALRM | 14 | Term | Timer signal from alarm(2) |
SIGTERM | 15 | Term | Termination signal |
SIGUSR1 | 30,10,16 | Term | User-defined signal 1 |
SIGUSR2 | 31,12,17 | Term | User-defined signal 2 |
SIGCHLD | 20,17,18 | Ign | Child stopped or terminated |
SIGCONT | 19,18,25 | Cont | Continue if stopped |
SIGSTOP | 17,19,23 | Stop | Stop process |
SIGTSTP | 18,20,24 | Stop | Stop typed at tty |
SIGTTIN | 21,21,26 | Stop | tty input for background process |
SIGTTOU | 22,22,27 | Stop | tty output for background process |
2.1 Signal Names and Values
- each signal has a name, value, and default action.
sys/signal.h
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
#define SIGILL 4 /* illegal instruction (not reset when caught) */
#define SIGTRAP 5 /* trace trap (not reset when caught) */
#define SIGABRT 6 /* abort() */
#define SIGPOLL 7 /* pollable event ([XSR] generated, not supported) */
#define SIGFPE 8 /* floating point exception */
#define SIGKILL 9 /* kill (cannot be caught or ignored) */
2.2 Default Actions of Signals
动作 | 描述 |
---|---|
Term | The process will terminate |
Core | The process will terminate and produce a core dump file that traces the process state at the time of termination. |
Ign | The process will ignore the signal |
Stop | The process will stop, like with a Ctrl-Z |
Cont | The process will continue from being stopped |
3 Signals from the Command Line
3.1 Preparing for the kill
3.2 Sending Terminal Signals with Kill
4 Handling and Generating Signals
4.1 Hello world of Signal Handling
1.int signal(int signum, void (*handler)(int))
2.参数1,接收到的信号 参数2:接收到指定信号后调用的函数
#include <stdlib.h>
#include <stdio.h>
#include <signal.h> /*for signal() and raise()*/
void hello(int signum){
printf("Hello World!\n");
}
int main(){
//execute hello() when receiving signal SIGUSR1
signal(SIGUSR1, hello); //再执行
//send SIGUSR1 to the calling process
raise(SIGUSR1); //先执行
}
4.2 Asynchronous Execution
1.asynchronous,当程序接收到信号,会暂停,去处理信号,然后再接着刚才的暂停继续执行
2.下面的程序无法用ctrl+c
来退出,因为程序接收到ctrl+c的信号后,会执行hello,然后继续循环.所以可以发送ctrl + \
来停止发送SIGSTOP
信号,此信号不能被处理和忽略
/* hello_loop.c*/
void hello(int signum){
printf("Hello World!\n");
}
int main(){
//Handle SIGINT with hello
signal(SIGINT, hello);
//loop forever!
while(1);
}
4.3 Inter Process Communication
1.int kill(pid_t pid, int signum);
2. `kill函数
/*ipc_signal.c*/
void hello(){
printf("Hello World!\n");
}
int main(){
pid_t cpid;
pid_t ppid;
//set handler for SIGUSR1 to hello()
signal(SIGUSR1, hello);
if ( (cpid = fork()) == 0){
/*CHILD*/
//get parent's pid
ppid = getppid();
//send SIGUSR1 signal to parrent
kill(ppid, SIGUSR1);
exit(0);
}else{
/*PARENT*/
//just wait for child to terminate
wait(NULL);
}
}
4.4 Ignoring Signals
- 忽略信号有两种方法
- SIG_IGN : Ignore the signal
- SIG_DFL : Replace the current signal handler with the default handler
int main(){
// using SIG_IGN
signal(SIGINT, SIG_IGN);
while(1);
}
4.5 Changing and Reverting to the default handler
1.在handler中可以再次接收信号
/*you_shot_me.c*/
void handler_3(int signum){
printf("Don't you dare shoot me one more time!\n");
//Revert to default handler, will exit on next SIGINT
signal(SIGINT, SIG_DFL);
}
void handler_2(int signum){
printf("Hey, you shot me again!\n");
//switch handler to handler_3
signal(SIGINT, handler_3);
}
void handler_1(int signum){
printf("You shot me!\n");
//switch handler to handler_2
signal(SIGINT, handler_2);
}
int main(){
//Handle SIGINT with handler_1
signal(SIGINT, handler_1);
//loop forever!
while(1);
}
4.6 Some signals are more equal than others
1.SIGSTOP
ctrl+z
不可处理
/* ignore_stop.c */
int main(){
//ignore SIGSTOP ?
signal(SIGSTOP, SIG_IGN);
//infinite loop
while(1);
}
2.SIGKILL
kill -SIGKILL
不可处理
int main(){
//ignore SIGSTOP ?
signal(SIGKILL, SIG_IGN);
//infinite loop
while(1);
}
4.7 Checking Errors of signal()
/*signal_errorcheck.c*/
int main(){
//ignore SIGSTOP ?
if( signal(SIGKILL, SIG_IGN) == SIG_ERR){
perror("signal");;
exit(1);
}
//infinite loop
while(1);
}