Linux signal Signal Processing mechanism (ZZ)

Source: Internet
Author: User
Tags emit posix terminates


signal is a very important part of Linux programming, this article will detail the basic concept of signal mechanism, the approximate realization method of Linux to signal mechanism, how to use signal, and several system calls about signal.

signal mechanism is a method of transmitting messages between processes, which is called soft interrupt signal, and some people call it soft interrupt. It can be seen from its nomenclature that its substance and use are much like interruptions. Therefore, the signal can be said to be part of the process control.

first, the basic concept of the signal

This section first introduces some basic concepts of the signal and then gives some basic signal types and events corresponding to the signals. The basic concepts are particularly important for understanding and using signals in the comprehension of signal mechanisms. Here's a look at what the signal is.

1. Basic Concepts

a soft interrupt signal (signal, also referred to as a signal) is used to notify the process that an asynchronous event has occurred. Processes can send soft interrupt signals to each other through system call kill. The kernel can also send a signal to the process because of an internal event, notifying the process that an event has occurred. Note that the signal is only used to notify a process of what has happened and does not pass any data to the process.

The process of receiving signals has different processing methods for various signals. The processing method can be divided into three categories: the first is similar to the interrupt handler, for the signal to be processed, the process can specify a handler function, which is handled by the function. The second method is to ignore a signal and do nothing about it, as if it had not happened. The third method is that the processing of the signal retains the default value of the system, and the default operation for most signals is to cause the process to terminate. The process calls signal through the system to specify the processing behavior of a process for a signal.

There is a soft interrupt signal field in the table entry for the process table, where each bit of the field corresponds to a signal that corresponds to the position bit when a signal is sent to the process. As you can see, the process can keep the different signals at the same time, but for the same signal, the process does not know how many have come before processing.

2. Type of signal

There are many reasons for signaling, which are simply categorized by the cause of the signal to understand the various signals:

(1) signals related to the termination of the process. This type of signal is emitted when the process exits, or when the child process terminates.
(2) signals related to process exception events. such as a process that is out of bounds, or an attempt to write a read-only memory area (such as a program body area), or perform a privileged instruction and various other hardware errors.
(3) a signal associated with an unrecoverable condition encountered during a system call. If the system calls exec, the original resources have been freed, and the system resources are now exhausted.
(4) a signal related to the non-predictive error condition encountered while executing the system call. such as executing a system call that does not exist.
(5) A signal sent by the process in the user state. As the process calls the system, call kill to send a signal to other processes.
(6) signal associated with the terminal interaction. If the user closes a terminal, or presses the break key, and so on.
(7) trace the signal of the process execution.

the list of supported Linux signals is as follows. Many of the signals are related to the architecture of the machine, and the signals listed in Posix.1 are listed first:

signal Value processing action causes the signal
SIGHUP 1 A terminal hangs or the control process terminates
SIGINT 2 A keyboard interrupt (if the break key is pressed)
sigquit 3 C keyboard exit key is pressed
Sigill 4 C illegal instruction
SIGABRT 6 C exit instruction issued by abort (3)
SIGFPE 8 C Floating-point exception
SIGKILL 9 AEF kill signal
SIGSEGV-C Invalid memory reference
Sigpipe A pipeline rupture: write a pipeline without a read port
SIGALRM a signal sent by alarm (2)
SIGTERM A Stop signal
SIGUSR1 30,10,16 A user-defined signal 1
SIGUSR2 31,12,17 A user-defined signal 2
SIGCHLD 20,17,18 B Sub-process end signal
Sigcont 19,18,25 Process continues (a process that has been stopped)
SIGSTOP 17,19,23 DEF terminating process
SIGTSTP 18,20,24 D control Terminal (TTY) press the STOP key
sigttin 21,21,26 D Background process attempts to read from the control terminal
Sigttou 22,22,27 D Background process attempts to write from the control terminal

The following signals are not listed in Posix.1, but are listed in SUSv2

signal Value processing action causes the signal
sigbus 10,7,10 C bus error (bad memory access)
Sigpoll a Sys v-defined pollable event, synonymous with Sigio
sigprof 27,27,29 A profiling timer to
sigsys,-, C Invalid system call (SVID)
SIGTRAP 5 C Trace/breakpoint Capture
Sigurg 16,23,21 B Socket Emergency condition (4.2 BSD)
sigvtalrm 26,26,28 A real time alarm clock signal (4.2 BSD)
sigxcpu 24,24,30 C exceeds the set CPU time limit (4.2 BSD)
Sigxfsz 25,25,31 C exceeds the set file size limit (4.2 BSD)

(for Sigsys,sigxcpu,sigxfsz, and the Sigbus,linux default action for some machine architectures is a (terminate), SUSv2 is C (Terminate and dump core).

Here are some other signals.

signal Value processing action causes the signal
Sigiot 6 C io capture instruction, synonymous with SIGABRT
sigemt 7,-, 7
sigstkflt-,16,-A coprocessor Stack error
SIGIO 23,29,22 A I/O operation is now available (4.2 BSD)
sigcld-,-, A and sigchld synonymous
SIGPWR 29,30,19 A power failure (System V)
siginfo,-,-A and SIGPWR synonymous
siglost-,-,-A file lock is missing
sigwinch 28,28,20 B window size change (4.3 BSD, Sun)
sigunused-,31,-A not used signal ('ll be Sigsys)

(here,-indicates that the signal is not implemented; three values give the meaning that the first value is usually valid on Alpha and SPARC, the median value corresponds to i386 and PPC, and SH, and the last value corresponds to MIPS.) The Signal 29 is SIGINFO/SIGPWR on Alpha and siglost on SPARC. )

the letters in an item of a processing action have the following meanings
a The default action is to terminate the process
B The default action is to ignore this signal
C The default action is to terminate the process and kernel image dumps (dump core)
D The default action is to stop the process
E-Signal cannot be captured
F signal cannot be ignored

The signals described above are supported by common systems. The names and functions of various signals and their processing actions by default are presented in tabular form. The meaning of the various default processing actions is that the terminating program refers to the process exiting; ignoring the signal is to discard the signal, not to do the processing, the Stop program is the program hangs, enter the stop condition can be restarted, usually in the process of debugging (such as Ptrace system call) Kernel image dump refers to the process data in the memory of the image and process stored in the kernel structure of the contents of a certain format dump to the file system, and the process exits execution, the advantage is to provide programmers with convenience, so that they can get the process at the time of execution of data values, allowing them to determine the reason for the dump, And can debug their programs.

Note that signals Sigkill and sigstop can neither be captured nor ignored. Signal Sigiot and SIGABRT are a signal. It can be seen that the same signal may not be the same in different systems, so it is advisable to use the name defined for the signal rather than using the value of the signal directly.

second, the signal mechanism

The basic concept of the signal is described in the previous section, where we will describe how the kernel implements the signaling mechanism. That is, how the kernel sends a signal to a process, how the process receives a signal, how the process controls its response to the signal, what time the kernel handles it, and how the process receives the signal. Also to introduce the role of setjmp and longjmp in the signal.

1, the core of the basic signal processing method

The method by which the kernel sends a soft interrupt signal to a process is the bit that corresponds to the signal field of the process table entry where the process is located. This is to add that if the signal is sent to a sleeping process, then the process goes to sleep priority, and if the process sleeps at an interruptible priority, the process is awakened, otherwise only the corresponding bit of the signal field in the process table is set and the process is not awakened. This is important because the process checks whether the signal is received when a process is about to return from the kernel state to the user state, or when a process is going to enter or leave an appropriate low-dispatch priority sleep state.

The time the kernel handles a signal received by a process is when a process returns to the user state from the kernel state. Therefore, when a process is running in the kernel state, the soft interrupt signal does not work immediately, and is not processed until it returns to the user state. The process will return to the user state only after processing the signal, and the process will not have an unhandled signal in the user state.

The kernel handles a process that receives a soft interrupt signal in the context of the process, so the process must be running. In the previous introduction of the concept, there are three types of processing signals: the process receives the signal and exits, the process ignores the signal, and the process receives the signal and executes the user-defined function that calls signal with the system. When a process receives a signal it ignores, the process discards the signal and continues to run as if it had not received the signal. If the process receives a signal to be captured, the process executes the user-defined function from the kernel state when it returns to the user state. And the way to execute a user-defined function is ingenious, the kernel is to create a new layer on the user stack, which sets the value of the return address to the address of the user-defined handler, so that the process returns to the user-defined function when the kernel returns to the top of the pop-up stack, from the function back to the top of the stack Before returning to the original kernel location. The reason for this is that the user-defined handler cannot and does not allow execution in the kernel state (if the user-defined function is running in the kernel state, the user can get any permissions).

in the signal processing method, there are a few special attention to be drawn. First, in some systems, the kernel clears the address of the processing routine for the signal that is set in the user area before the process has finished processing the interrupt signal, that is, the next process will process the signal to the default value unless the signal system call is used again before the next signal arrives. This may cause the process to exit by getting the signal again before calling signal. In BSD, the kernel no longer clears the address. But not clearing the address may cause the process to overflow because of too much too fast to get a signal. In order to avoid this situation. In BSD systems, the kernel simulates the processing of a hardware interrupt, which prevents a new interrupt from being received while processing an interrupt.

The second note is that if the signal to be captured occurs when the process is in a system call, and the process sleeps at an interruptible priority, then the signal causes the process to make a longjmp, jump out of sleep, return to the user state, and perform a signal processing routine. When returned from the signal processing routine, the process returns as if it were returned from a system call, but returns an error code indicating that the system call was interrupted. It is important to note that the kernel in the BSD system can automatically restart system calls.

The third thing to note: If the process sleeps on an interruptible priority, the process wakes up when it receives a signal to ignore, but does not do longjmp, and generally continues to sleep. But the user does not feel that the process has been awakened, but that the signal has not happened.

the fourth point to note: The kernel process termination (SIGCLD) Signal processing method differs from other signals. When the process checks for a signal that a child process has been received, by default the process is as if the signal was not received, and if the parent process executes a system call to wait, the process wakes from the system call wait and returns the wait call, performing a series of subsequent operations on the wait call (finding the zombie subprocess, Release the process table entry for the child process, and then return from wait. The function of the SIGCLD signal is to wake up a process of sleep on the interruptible priority. If the process captures this signal, it goes to the processing routine just like normal signal processing. If the process ignores the signal, then the system calls the wait action differently, because the SIGCLD is only to wake up a process that sleeps on the interruptible priority, then the parent process that executes the wait call is woken up to continue with the wait call, and then waits for the other child processes.

If a process calls the signal system call and sets the processing method for SIGCLD, and the process has a child process that is in a zombie state, the kernel sends a SIGCLD signal to the process.

2, the role of setjmp and longjmp

before introducing the signal processing mechanism, the setjmp and longjmp were mentioned several times, but the function and the method of implementation were not carefully explained. Here is a brief introduction to this.

when we introduce the signal, we see several places that require the process to return directly from the original system call after checking for a signal, rather than waiting for the call to complete. This process suddenly changes its context, which is the result of using setjmp and longjmp. SETJMP saves the context to the user area and continues to execute in the old context. This means that the process executes a system call, and when it is going to sleep because of resources or other reasons, the kernel makes a setjmp for the process, and if it wakes up in sleep and the process cannot go to sleep, the kernel calls longjmp for the process, which is the kernel Restores the context to the current context for the process to save the original setjmp call to the process user area, which allows the process to resume the state before it waits for the resource, and the kernel returns 1 for setjmp, allowing the process to know that the system call failed. That's how they work.

third, the system call about the signal

Most of the information about the signal is covered in the previous two sections. Let's take a look at these system calls in this section. wherein, the system call signal is the process used to set a signal processing method, system call Kill is used to send a signal to the specified process. These two calls can form the basic operation of the signal. The latter two calls to pause and alarm are implemented by signaling process pauses and timers, and calling alarm is signaled by signaling the process timer to the time. So here we are going to cover both of these calls.

1. Signal system call

the system calls signal to set a signal processing method. The invocation declaration is in the following format:
void (*signal (int signum, void (*handler) (int)))) (int);
Add the following header file to the process that uses the call:
#include <signal.h>

The above declaration format is complex and can be used in a format defined by the following type if it is not clear how to use it (POSIX definition):
typedef void (*sighandler_t) (int);
sighandler_t Signal (int signum, sighandler_t handler);
However, this format has different type definitions in different systems, so it is best to refer to the online manual for this format.

in the call, the parameter Signum indicates the signal to set the processing method. The second parameter, handler, is a handler function, or
sig_ign: Ignores the signal indicated by the parameter signum.
SIG_DFL: The default value is the processing method of the signal Signum by the recovery parameter.

the integer parameter passed to the signal processing routine is the signal value, which allows a signal processing routine to process multiple signals. The system call signal return value is the specified signal Signum the previous processing routine or error when the error code Sig_err is returned. Let's look at a simple example:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
void sigroutine (int dunno) {/* signal processing routine where dunno will get the value of the signal */
switch (dunno) {
Case 1:
printf ("Get a signal--SIGHUP");
Break ;
Case 2:
printf ("Get a signal--SIGINT");
Break ;
Case 3:
printf ("Get a signal--sigquit");
Break ;


int main () {
printf ("Process ID is%d", getpid ());
signal (SIGHUP, Sigroutine)//* the following three signal processing methods are set
signal (SIGINT, sigroutine);
signal (sigquit, sigroutine);
for (;;);

wherein the signal SIGINT from the press of Ctrl-c issued, the signal sigquit by pressing Ctrl-out. The results of the program execution are as follows:

process ID is 463
get a Signal-sigint//press CTRL-C to get results
get a Signal-sigquit//press CTRL to get results
//Press Ctrl-z to place the process in the background
[1]+ Stopped./sig_test
localhost:~$ BG
[1]+./sig_test &
localhost:~$ kill-hup 463//Send sighup signal to process
localhost:~$ Get a signal–sighup
kill-9 463//Send Sigkill signal to process, terminate process

2. Kill system Call

system call Kill is used to send a signal to the process. The invocation declaration is in the following format:
int Kill (pid_t pid, int sig);
Add the following header file to the process that uses the call:
#include <sys/types.h>
#include <signal.h>

This system call can be used to send any signal to any process or process group. If the parameter PID is a positive number, the call sends the signal SIG to a process with a PID. If the PID is equal to 0, then the signal sig is sent to all processes in the process group to which the current process belongs. If the parameter PID equals-1, the signal sig is sent to all processes except process 1 and itself. If the parameter PID is less than-1, the signal sig is sent to all processes that belong to the process group-pid. If the parameter sig is 0, no signal will be sent. When the call executes successfully, the return value is 0, the error returns 1, and the corresponding error code errno is set. Here are some of the error codes that may be returned:
EINVAL: The specified signal sig is not valid.
esrch: Parameter pid The specified process or process group does not exist. Note that the process that exists in the process table entry may be a zombie process that has not been recovered by wait, but has terminated execution.
Eperm: The process does not have the power to send this signal to the specified receiving signal. Because a process is allowed to send a signal to the process PID, it must either have root authority, or the UID or euid of the process that issued the call is the same as the UID or save user ID (Savedset-user-id) of the process that you specify to receive. If the parameter PID is less than-1, that is, the signal is sent to a group, the error indicates that a member process in the group cannot receive the signal.

3. Pause system Call

the function of the system call to pause is to wait for a signal. The invocation is declared in the following format:
int pause (void);
Add the following header file to the process that uses the call:
#include <unistd.h>

This call causes the process that makes the call to sleep until a signal is received. The call always returns-1 and sets the error code to EINTR (a signal is received). The following is a simple example:

#include <unistd.h>
#include <stdio.h>
#include <signal.h>
void Sigroutine (int unused) {
printf ("Catch a Signal SIGINT");

int main () {
signal (SIGINT, sigroutine);
pause ();
printf ("Receive a Signal");

in this example, the program begins to execute as if it had entered a dead loop, because the process is waiting for the signal, and when we press CTRL-C, the signal is captured and the pause exits the wait state.

4, Alarm and Setitimer system calls

the function of the system call alarm is to set a timer that will emit a signal to the process when the timer arrives. The invocation is declared in the following format:
unsigned int alarm (unsigned int seconds);
Add the following header file to the process that uses the call:
#include <unistd.h>

The system calls alarm to schedule the kernel to emit a SIGALRM signal for the calling process after the specified seconds seconds. If the specified parameter seconds is 0, the SIGALRM signal is no longer sent. The next setting cancels the previous setting. The call returns a value that is the time remaining between the last scheduled call to the send or 0 because there is no previous scheduled call.

Note that when used, the alarm is only set to send a signal once, and if it is to be sent multiple times, it will be called multiple times using alarm.

for Alarm, here is no longer an example. Many programs in the current system no longer use the alarm call, but instead use the Setitimer to set the timer, using the Getitimer to get the state of the timer, the declaration format of the two calls is as follows:
int Getitimer (int which, struct itimerval *value);
int Setitimer (int which, const struct itimerval *value, struct itimerval *ovalue);
Add the following header file to the process that uses the two calls:
#include <sys/time.h>

the system calls the process to provide three timers, each with its own unique timing domain, when any one arrives, sends a corresponding signal to the process, and causes the timer to start over again. The three timers are specified by the parameter which, as follows:
Timer_real: Timed to the actual time, the timing arrives will send the SIGALRM signal to the process.
itimer_virtual: Timing occurs only when the process is executing. The timed arrival will send a SIGVTALRM signal to the process.
itimer_prof: Timed when the process executes and when the system performs an action for the process. As with itimer_vir-tual, this timer is often used to count the time spent by the process in the user state and kernel state. The timed arrival will send a sigprof signal to the process.

the parameter value in the timer is used to indicate the time of the timer, and its structure is as follows:
struct Itimerval {
struct Timeval it_interval;/* Next value * /
struct Timeval it_value;/* Set value for this time * /

the structure of the TIMEVAL structure is defined as follows:
struct Timeval {
long tv_sec; */* seconds * /
long tv_usec;/* microseconds, 1 sec = 1000000 μs * /

in the Setitimer call, the parameter Ovalue if it is not empty, it retains the value of the last invocation setting. The timer decrements the It_value to 0 o'clock, generates a signal, sets the value of the It_value to It_interval value, and then restarts the chronograph, again and again. When It_value is set to 0 o'clock, the timer stops, or when it time expires, and It_interval stops at 0 o'clock. When the call succeeds, return 0; error, return-1, and set the corresponding error code errno:
efault: The parameter value or Ovalue is an invalid pointer.
EINVAL: Parameter which is not one of itimer_real, Itimer_virt, or itimer_prof.

here is a simple demonstration of the Setitimer call, in which a sigalrm is emitted every 0.5 seconds and a SIGVTALRM signal is emitted:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
int sec;

void sigroutine (int signo) {
switch (signo) {
printf ("Catch a Signal-sigalrm");
Break ;
printf ("Catch a Signal-sigvtalrm");
Break ;


int main () {
struct Itimerval value,ovalue,value2;
sec = 5;

printf ("Process ID is%d", getpid ());
signal (SIGALRM, sigroutine);
signal (SIGVTALRM, sigroutine);

value.it_value.tv_sec = 1;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 1;
value.it_interval.tv_usec = 0;
Setitimer (Itimer_real, &value, &ovalue);

value2.it_value.tv_sec = 0;
value2.it_value.tv_usec = 500000;
value2.it_interval.tv_sec = 0;
value2.it_interval.tv_usec = 500000;
Setitimer (itimer_virtual, &value2, &ovalue);

for (;;);

The screen copy of this example is as follows:

Process ID is 579

This article briefly describes the signals under Linux, and if you want to know about other calls, refer to the online manuals or other documentation.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.