1. Basic concept of signal
A signal is an event generated by the system in response to a condition. The process will perform the corresponding operation after receiving the signal. System calls related to signals are declared in the "signal.h" header file.
Values of common signals and corresponding function descriptions:
The value of the signal is defined in the system source code as follows:
#define SIGHUP 1 #define SIGINT 2 / / this signal is generated when you press Ctrl+c on the keyboard #define SIGQUIT 3 #define SIGILL 4 #define SIGTRAP 5 #define SIGABRT 6 #define SIGIOT 6 #define SIGBUS 7 #define SIGFPE 8 #define SIGKILL 9 / / the response mode of this signal cannot be changed #define SIGUSR1 10 #define SIGSEGV 11 #define SIGUSR2 12 #define SIGPIPE 13 / / a descriptor closed by the reader. This message is generated when the writer writes No. 1 will terminate the program #define SIGALRM 14 #define SIGTERM 15 / / the system uses the kill command to send signals by default #define SIGSTKFLT 16 #define SIGCHLD 17 / / after the child process ends, the message will be sent to the parent process by default number #define SIGCONT 18 #define SIGSTOP 19 #define SIGTSTP 20 #define SIGTTIN 21 #define SIGTTOU 22 #define SIGURG 23
2. Modify the response mode of the signal – signal()
2.1 modify SIGINT (i.e. Ctral+C) signal response mode
Pressing Ctrl+c on the keyboard will send a SIGINT signal to the process executed in the foreground of the current terminal. Use signal to modify the response mode of SIGINT signal. The example code is as follows:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include<signal.h> void fun(int sig) { sleep(5); printf("sig = %d\n",sig); } int main() { signal(SIGINT,fun); while(1) { printf("hello\n"); sleep(1); } }
The fun function is not called here. We pass it to signal in the form of parameters. If the signal is triggered, the system will call the fun function, so the fun function is a callback function.
Signal does not call back the fun function at first. After receiving the signal, the program will interrupt to deal with the signal problem. After dealing with the signal problem, the system will continue to execute.
Execution results:
When the program is running, when we execute Ctrl+C, the program will call back the fun function, sleep for five seconds, print sig, process the signal, and then continue to execute the program.
2.2 modify the modified signal response mode to default
So how to modify the signal to the original corresponding way again? Replace the second parameter of signal with SIG_DFL can be used to show us:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include<signal.h> void fun(int sig) { sleep(3); printf("sig = %d\n",sig); signal(SIGINT,SIG_DFL);//Change the corresponding signal mode to default } int main() { signal(SIGINT,fun); while(1) { printf("hello\n"); sleep(1); } }
Operation results:
At the first Ctral+C, the system calls back the fun function, sleeps for 5 seconds, outputs sig, and modifies the Ctral+C response mode to the default mode. Therefore, at the second Ctral+C, the program normally responds to the signal and interrupts the operation of the program.
2.3 ignore signal
To ignore the signal, you only need to replace the second parameter of signal with SIG_IGN can be used to show us:
code:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include<signal.h> int main() { signal(SIGINT,SIG_IGN); while(1) { printf("hello\n"); sleep(1); } }
Operation results:
The signal Ctral+C is ignored, so Ctral+C does not respond and the program is not affected.
3. Send signal – kill()
kill() can send the specified signal to the specified process:
int kill(pid_t pid, int sig);
PID > 0 specifies which process to send the signal to.
The pid == 0 signal will be sent to the process in the same process group as the current process.
pid == -1 sends the signal to all processes on the system that have permission to send.
pid < - 1 sends a signal to all processes whose process group id is equal to the absolute value of pid and has permission to send.
sig specifies the type of signal to send.
The program similar to the system kill command using the kill() system call is as follows:
#include<stdio.h> #include<stdlib.h> #include<assert.h> #include<unistd.h> #include<signal.h> //. / main PID sig three parameters int main(int argc,char* argv[]) { if(argc != 3) { printf("arg error\n"); exit(0); } int pid = 0; int sig = 0; sscanf(argv[1],"%d",&pid); sscanf(argv[2],"%d",&sig); if(kill(pid,sig) == -1) { perror("kill error"); } exit(0); }
test.c is a program with unlimited Hello output. Running test will continuously print hello
When we find the pid number of test in another terminal, we use mykill written by ourselves to send a signal to test.
Then it was found that test was interrupted. (2) the signal is SIGINT signal, which is the signal sent by Ctral+C).
#define SIGKILL 9 / / the response mode of this signal cannot be changed
#define SIGTERM 15 / / the system uses the kill command to send signals by default
We change 2 to 9 or 15, which is equivalent to pkill forced end or kill end for pid. Signal 9 does not allow the response mode to be modified to deal with all processes.