19 Signals and Signal Handling

佐手、 提交于 2019-12-23 00:16:39

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

  1. each signal has a name, value, and default action.
  2. 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

  1. 忽略信号有两种方法
    1. SIG_IGN : Ignore the signal
    2. 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);

}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!