Linux signal mechanism Detailed explanation

  

linux signal mechanism is far more complicated than imagined, this article strives to use the shortest space to make in-depth and detailed analysis of the mechanism.

1. Signals and Signal Sources

Signal Essence

A signal is a simulation of the interrupt mechanism at the software level. In principle, a process receives a signal. It can be said that the processor receives an interrupt request. The signal is asynchronous, and a process does not have to wait for any signal to arrive. In fact, the process does not know when the signal arrives.

Signal is the only asynchronous communication mechanism in the interprocess communication mechanism. It can be regarded as an asynchronous notification, which informs the process of receiving signals that something has happened. The signal mechanism is more powerful after being extended by POSIX in real time. In addition to the basic notification function, additional information can be transmitted.

Signal Sources

Signal events occur in two sources: hardware sources (such as when we press a keyboard or other hardware failure); software sources, the most commonly used system function to send signals is kill , raise, alarm and setitimer and sigqueue functions, the software source also includes some illegal operations.

Second, the type of signal

can classify the signal from two different classification angles: (1) reliability: reliable signal and unreliable signal 唬?) and time relationship Top: Real-time signals and non-real-time signals. All signals supported by the system are listed in Appendix 1 of "Inter-Process Communication in Linux Environment (1): Pipes and Named Pipes".

1, reliable signals and unreliable signals

"unreliable signals"

The Linux signaling mechanism is basically inherited from Unix systems. The signal mechanism in the early Unix system was relatively simple and primitive, and later exposed some problems in practice. Therefore, the signals established on the early mechanism are called "unreliable signals", and the signal value is less than SIGRTMIN (Red Hat 7.2) The signals of SIGRTMIN=32, SIGRTMAX=63) are all unreliable signals. This is the source of "unreliable signals". Its main problem is:

After processing the signal, the process sets the response to the signal to the default action. In some cases, this will result in error handling of the signal; therefore, if the user does not want such an operation, then signal() is called again at the end of the signal handler to reinstall the signal.

The signal may be lost, as will be explained in more detail later.

Therefore, the unreliable signal in the early Unix mainly refers to the fact that the process may respond incorrectly to the signal and the signal may be lost.

Linux supports unreliable signals, but improves the unreliable signal mechanism: after calling the signal processing function, it is not necessary to recall the installation function of the signal (the signal installation function is implemented on a reliable mechanism) . Therefore, the unreliable signal problem under Linux mainly refers to the possibility that the signal may be lost.

"Reliable Signals"

As time progresses, practice has proven that it is necessary to improve and extend the original mechanism of the signal. Therefore, various Unix versions that appeared later have been studied in this respect, and strive to achieve "reliable signal". Since the original defined signal has many applications, it is not easy to make changes. Finally, some new signals have been added, and they are defined as reliable signals at the beginning. These signals support queuing and will not be lost. At the same time, new versions of the signal are sent and installed: the signal transmission function sigqueue () and the signal installation function sigaction (). POSIX.4 standardizes the reliable signaling mechanism. However, POSIX only standardizes the functions of the reliable signal mechanism and the external interface of the signal mechanism, and does not specify the implementation of the signal mechanism.

Signal values ​​between SIGRTMIN and SIGRTMAX are reliable signals, and reliable signals overcome the problem of possible signal loss. While supporting the new version of the signal installation function sigation() and the signal sending function sigqueue(), Linux still supports the early signal () signal installation function and supports the signal sending function kill().

Note: Don't have such a misunderstanding: the signal sent by sigqueue() and sigaction is reliable. In fact, a reliable signal is a new signal that is added later (the signal value is between SIGRTMIN and SIGRTMAX); an unreliable signal is a signal with a signal value less than SIGRTMIN. The reliability and unreliability of the signal are only related to the signal value, independent of the signal transmission and installation functions. Currently, signal() in linux is implemented by the sigation() function. Therefore, even if the signal is installed by signal(), the signal installation function does not need to be called at the end of the signal processing function. At the same time, the real-time signal installed by signal() supports queuing and will not be lost.

For the current two Linux signal installation functions: signal() and sigaction(), they can't turn SIGRTMIN's previous signal into a reliable signal (no support for queuing, it is still possible to lose, still It is an unreliable signal), and it supports queuing for signals after SIGRTMIN. The biggest difference between these two functions is that the signal installed by sigaction can pass information to the signal processing function (which is true for all signals), while the signal installed by signal cannot pass information to the signal processing function. The same is true for the signaling function.

2, real-time signals and non-real-time signals

In the early Unix system, only 32 kinds of signals were defined. Ret hat7.2 supports 64 kinds of signals, number 0-63 (SIGRTMIN=31, SIGRTMAX= 63), may increase further in the future, which needs to be supported by the kernel. The first 32 signals already have predefined values, each signal has a defined purpose and meaning, and each signal has its own default action. If you press CTRL ^ C on the keyboard, a SIGINT signal is generated, and the default response to this signal is the process termination. The last 32 signals represent real-time signals, equivalent to the reliable signals set forth above. This ensures that multiple real-time signals sent are received. Real-time signals are part of the POSIX standard and can be used in application processes.

Non-real-time signals do not support queuing and are unreliable signals; real-time signals support queuing and are reliable signals.

Three, the process response to the signal

The process can respond to a signal in three ways: (1) ignore the signal, that is, do not do any processing on the signal, of which there are two signals Cannot be ignored: SIGKILL and SIGSTOP; (2) capture signal. Define the signal processing function, when the signal occurs, execute the corresponding processing function; (3) Perform the default operation, Linux specifies the default operation for each signal, please refer to [2] and other materials for details. Note that the default response of the process to real-time signals is the process termination.

Which of Linux uses the above three methods to respond to signals, depending on the parameters passed to the corresponding API function.

Four, signal transmission

The main functions of sending signals are: kill(), raise(), sigqueue(), alarm(), setitimer(), and abort().

1, kill()

#include <sys/types.h>

#include <signal.h>

int kill( Pid_t pid, int signo)

The receiving process of the parameter pid value signal

pid>0 Process with process ID pid

pid=0 Process of the same process group

pid<0 pid!=-1 All processes with process group ID -pid

pid=-1 All processes with process ID greater than 1 except for the sending process itself

Sinno is the signal value. When it is 0 (that is, the null signal), no signal is actually sent, but the error check is performed as usual. Therefore, it can be used to check whether the target process exists and whether the current process has the right to send a signal to the target. (A root-privileged process can send a signal to any process. A process with non-root privileges can only send signals to processes belonging to the same session or the same user).

Copyright © Windows knowledge All Rights Reserved