In Linux, a signal is a way of communicating between processes, and it uses an asynchronous mechanism. When the signal is sent to a process, the operating system interrupts the normal process of the process and enters the appropriate signal handler to perform the operation, and then goes back to where it was interrupted.
It is necessary to note that the signal is only used to notify the process that an event has occurred, in addition to the information of the signal itself, does not have the ability to pass user data.
1 response action of the signal
Each signal has its own response action, when the signal is received, the process will be based on the response action of the signal to perform the corresponding action, the signal response action has the following:
- Abort process (term)
- Ignore signal (IGN)
- Abort process and save memory information (Core)
- Stop process (STOP)
- Continue running Process (Cont)
The user can signal
sigaction
Modify the response action of the signal via or function (that is, the "registered signal", which is described later in the article). In addition, in multi-threading, the signal response actions of each thread are the same, and a separate response action cannot be set on a thread.
2 Signal Type
The types of signals supported by Linux can refer to the list given below.
2.1 List of signals in the posix.1-1990 standard
Signal |
value |
Action |
Description |
SIGHUP |
1 |
Term |
Terminal Control process End (terminal connection disconnected) |
SIGINT |
2 |
Term |
User sends Intr character (CTRL + C) trigger |
Sigquit |
3 |
Core |
User sends the Quit character (ctrl+/) trigger |
Sigill |
4 |
Core |
Illegal instruction (program error, attempt to execute data segment, stack overflow, etc.) |
Sigabrt |
6 |
Core |
Call the Abort function to trigger |
SIGFPE |
8 |
Core |
Arithmetic run error (floating-point arithmetic error, divisor is zero, etc.) |
SIGKILL |
9 |
Term |
Unconditional End Program (cannot be captured, blocked, or ignored) |
SIGSEGV |
11 |
Core |
Invalid memory reference (attempting to access memory space that does not belong to itself, write to read-only memory space) |
Sigpipe |
13 |
Term |
Message pipeline Corruption (Fifo/socket communication, the pipeline is not open and writes) |
Sigalrm |
14 |
Term |
Clock timing Signal |
SIGTERM |
15 |
Term |
End program (can be captured, blocked, or ignored) |
SIGUSR1 |
30,10,16 |
Term |
User Retention |
SIGUSR2 |
31,12,17 |
Term |
User Retention |
SIGCHLD |
20,17,18 |
Ign |
Child process End (received by parent process) |
Sigcont |
19,18,25 |
Cont |
Continue execution of stopped processes (cannot be blocked) |
SIGSTOP |
17,19,23 |
Stop |
Stop a process (cannot be caught, blocked, or ignored) |
Sigtstp |
18,20,24 |
Stop |
Stop a process (can be caught, blocked, or ignored) |
Sigttin |
21,21,26 |
Stop |
Triggers when the daemon reads data from the terminal |
Sigttou |
22,22,27 |
Stop |
Triggers when a background program writes data to the terminal |
Note : These SIGKILL
and SIGSTOP
signals cannot be captured, blocked, or ignored.
2.2 List of signals in the SUSV2 and posix.1-2001 standards
Signal |
value |
Action |
Description |
SIGTRAP |
5 |
Core |
trap instruction trigger (such as breakpoint, used in debugger) |
sigbus |
0,7,10 |
Core |
Illegal address (memory address alignment error) |
sigpoll |
|
Te RM |
pollable Event (Sys V). Synonym for SIGIO |
sigprof |
27,27,29 |
term |
performance clock signal with system call time and process consuming CPU Room) |
sigsys |
12,31,12 |
Core |
Invalid system call (SVR4) |
SIG URG |
16,23,21 |
Ign |
have emergency data arrival socket (4.2BSD) |
sigvtalrm |
26, 26 , |
term |
virtual clock signal (process consuming CPU time) (4.2BSD) |
sigxcpu |
24,24,30 |
C Ore |
exceeded CPU time resource limit (4.2BSD) |
sigxfsz |
25,25,31 |
Core |
exceeds file size resource Limit (4.2BSD) |
Note : The default response SIGSYS
SIGXCPU
SIGXFSZ
SIGBUS
Action for these three signals is changed to core before the Linux 2.2 release, and the default response action is Term,linux 2.4.
2.3 Other signals
Signal |
value |
Action |
Description |
Sigiot |
6 |
Core |
IoT capture signal (same as SIGABRT signal) |
sigemt |
7,-, 7 |
term |
Real-time hardware error |
sigstkflt |
-,16,- |
term |
co-processor stack error (not used) |
SIGIO |
23,29,22 |
term |
file descriptor Ready (can start input/output operation) (4.2BSD) |
sigcld |
-,-, |
Ign |
Child process End (received by parent process) (with SIGCHLD signal) |
sigpwr |
29,30,19 |
term |
power error (System V) |
siginfo |
,-,- |
|
Power error (same as SIGPWR signal) |
siglost |
-,-,- |
term |
file lock missing (not used) |
sigwinch |
28,28,20 |
Ign |
window size changed (4.3BSD, Sun) |
sigunused |
-,31,- |
Core |
Invalid system call (with Sigsys signal) |
Note : Some of the signals in the list have three values because the values of the partial signals are related to the CPU architecture, the values of these signals are different in the CPU of the different architectures, and the three values are arranged in the order of: 1,alpha/sparc;2,x86/arm/others;3, Mips.
For example SIGSTOP
, this signal has three possible values, 17, 19, 23, where the first value (17) is used in the alpha and SPARC architectures, the second value (19) is used in other architectures such as x86, ARM, and the third value (23) is used in the MIPS schema.
3 Signal mechanism
As mentioned earlier in the article, the signal is asynchronous, which involves when the signal is received and when it is processed.
We know that the function is running in the user state, and when a system call, interrupt, or exception is encountered, the program enters the kernel state. The signal involves a conversion between the two States, and the process can look at the following:
Next, the signal is divided into receiving, detecting and processing three parts, each of which explains the process of each step.
3.1 Reception of the signal
The task that receives the signal is the kernel agent, and when the kernel receives the signal, it is placed in the signal queue of the corresponding process and sends an interrupt to the process to get it into the kernel state.
Note that at this point the signal is still only in the queue, and for the time being the process is unaware of the signal coming.
3.2 Detection of Signals
After the process is in the kernel state, there are two scenarios where the signal is detected:
- Process signal detection before returning from kernel state to user state
- Process in the kernel state, signal detection from the time the sleep state is awakened
When a new signal is found, it will go to the next step, signal processing.
3.3 Processing of signals
The signal processing function is run in the user state, before invoking the handler function, the kernel will copy the content backup of the current kernel stack to the user stack, and modify the instruction register (EIP) to point to the signal processing function.
The process then returns to the user state and executes the corresponding signal processing function.
After the signal processing function is completed, it is also necessary to return to the kernel state to check if there are other signals not being processed. If all the signals are processed, the kernel stack will be restored (back from the backup copy of the user stack), and the Command Register (EIP) will be directed to the running position before the interrupt, and then the user state continues the execution process.
At this point, a complete signal processing process is over, and if multiple signals arrive at the same time, the above process will be repeated between steps 2nd and 3rd.
Focus on understanding three parts: signal detection/signal call/Signal processing program return. Understand how to process from normal process to signal handler to normal process.
4 Use of Signal 4.1 send signal
The functions used to send signals are,,,,,, and the raise
kill
killpg
pthread_kill
tgkill
sigqueue
Meanings and usages of these functions are very similar, here we mainly introduce the common raise
kill
functions.
raise function : Sends a signal to the process itself
The function declaration is as follows:
#include <signal.h>raise(sig);
The function function is to send a signal to the current program (itself), where sig
the parameter is the signal value.
kill function : Sends a signal to the specified process
The function declaration is as follows:
#include <sys/types.h>#include <signal.h>kill(pidsig);
The function function is to send a signal to a particular process, where the parameter is the pid
process number, which is the sig
signal value.
Here the parameters pid
, depending on the range of values, the meaning is also different, the specific description is as follows:
- PID > 0: Send signal to process number PID
- PID = 0: Sends a signal to the process group where the current process resides
- PID =-1: Sends a signal to all processes (except pid=1) (within the purview)
- PID <-1: Send signal to all processes with process group number-pid
In addition, when the sig
value is zero, no signal is actually sent, but the function return value is still valid and can be used to check whether the process exists.
4.2 Wait for the signal to be captured
The process of waiting for a signal is actually pausing the current process (thread) until a signal is sent to the current process (thread) and captured, and the function has a pause
sigsuspend
.
pause function : Moves the process (or thread) to sleep until the signal is received
The function declaration is as follows:
#include <unistd.h>pause(void);
After the function is called, the caller (process or thread) enters the sleep state until the (arbitrary) signal is captured. The function's return value is always-1, and after the call is finished, the error code (errno) is set to Eintr.
sigsuspend function : Moves a process (or thread) to sleep until a specific signal is received
The function declaration is as follows:
#include <signal.h>sigsuspend(*mask);
After the function is called, the signal mask of the process is temporarily modified (parameters mask
), and then the process is paused until a signal that matches the condition is received and the signal mask before the call is resumed before the function returns. The function's return value is always-1, and after the call is finished, the error code (errno) is set to Eintr.
4.3 Modifying the response action of the signal
The user can redefine the way a signal is handled by itself, that is, the default response action of the previously mentioned modification signal, or it can be understood as the registration of a signal, which can be carried out by a function, as illustrated by a signal
sigaction
signal
function.
First look at the function declaration:
#include <signal.h>(*sighandler_t) (int); Signal(signumhandler);
The first parameter signum
is the signal value, which can be found from the preceding signal list, and the second parameter handler
is the handler function, which is invoked when the signal is triggered by a callback method.
The following is the sample code:
#include <stdio.h>#include <signal.h>#include <unistd.h>/* Signal processing function */voidSig_callback(IntSignum){Switch(Signum){CaseSIGINT:/* SIGINT:CTRL+C trigger when pressed */Printf("Get signal SIGINT.\ r \ n");Break;/* Multiple signals can be placed in the same function to differentiate by signal value */Default/* Other Signals */Printf("Unknown signal%d.\ r \ n",Signum);Break;}Return;}/* Main function */IntMain(Intargc,Char*Argv[]){Printf (" Register SIGINT (%u) Signal Action. \r\n "sigint); /* registered SIGINT Signal processing function */signal (sigint sig_callback); printf ( "waitting for Signal ... \r\n "); /* wait for signal trigger */pause (); printf ( "Process Continue. \r\n "); return 0;}
Source File Download: Link
Example, the SIGINT
action of the signal ( Ctrl+C
trigger) takes over (print the hint message), after the program runs, press Ctrl+C
, the command line output is as follows:
. /linux_signal_exampleSIGINT(2Action^SIGINTContinue.
After the process receives the SIGINT
signal, it triggers the response action, prints the message, and then resumes running from where it was paused. It is important to note that since we have modified the SIGINT
response action of the signal (only printing information, not process exit processing), after we press Ctrl+C
, the program does not exit directly, but continues to run and "process Continue." Print out until the program ends properly.
Reprint: http://hutaow.com/blog/2013/10/19/linux-signal/