Linux Signal Processing Three

Source: Internet
Author: User
Tags function prototype posix sigint signal signal handler

First, signal and signal source

Signal Essence

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

The signal is the only asynchronous communication mechanism in the interprocess communication mechanism, which can be regarded as asynchronous notification and what happens in the process of notifying the receiving signal. After POSIX real-time expansion, the signaling mechanism is more powerful and can deliver additional information in addition to the basic notification function.

Signal source

There are two sources of signal events: hardware sources (e.g. we press keyboards or other hardware failures), software sources, the most common system functions for sending signals are kill, raise, alarm and setitimer, and Sigqueue functions, and software sources include operations such as illegal operations.

Back to top of page

Ii. Types of Signals

The signals can be categorized from two different classification angles: (1) Reliability: Reliable and unreliable signals, and (2) Relationship to time: real-time and non-real-time signals. All signals supported by the system are listed in the attached 1 to the Linux environment interprocess communication (i): Pipelines and famous pipelines.

1. Reliable signal and unreliable signal

"Unreliable signal"

The Linux signaling mechanism is basically inherited from Unix systems. The signaling mechanisms in the early UNIX system were relatively simple and primitive, and later exposed some problems in practice, so the signals that were built on the early mechanisms were called "unreliable signals" with a signal value less than sigrtmin (Red hat 7.2, sigrtmin=32,sigrtmax= 63) signals are unreliable signals. This is the source of "unreliable signals". The main problems of it are:

    • Each time the process processes the signal, the response to the signal is set to the default action. In some cases, it will cause error handling of the signal, so if the user does not want to do so, it is necessary to re-install the signal by calling signal () at the end of the signal processing function.
    • The signal may be lost, which will be described in more detail later.
      Therefore, unreliable signals in the early stages of Unix mainly mean that the process may react incorrectly to the signal and the signal may be lost.

Linux supports unreliable signaling, but improves the unreliable signaling mechanism: after the signal processing function is called, 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 means that the signal may be lost.

"Reliable signal"

With the development of time, the practice proves that it is necessary to improve and expand the original mechanism of signal. As a result, later versions of Unix have been studied in this area, trying to achieve "reliable signals". Since there are many applications for the previously defined signals, it is not good to make any changes, and eventually we have to add some new signals and define them as reliable signals at the outset, which support queuing and will not be lost. At the same time, the signal transmission and installation also appeared a new version: Signal transmission function sigqueue () and Signal installation function sigaction (). The posix.4 is standardized for reliable signaling mechanisms. However, POSIX only standardizes the function of the reliable signal mechanism and the external interface of the signal mechanism, and makes no specific provision for the realization of the signal mechanism.

Signals that are located between Sigrtmin and Sigrtmax are reliable signals that overcome the potential loss of the signal. While Linux supports the new version of the signal installation function sigation () and the signal sending function sigqueue (), it still supports the early signal () signal installation function, which supports the signal sending function kill ().

Note: There is no such misunderstanding: the signal sent by Sigqueue () and sigaction installed is reliable. In fact, a reliable signal is a new signal added later (the signal value is located between Sigrtmin and Sigrtmax); The unreliable signal is a signal with a signal value less than sigrtmin. The reliable and unreliable signal is only related to the signal value, and is independent of the sending and installing function of the signal. Currently, signal () in Linux is implemented through the sigation () function, so even if the signal is installed through the signal (), the signal handler function is not required to be called at the end of the signal processing function. At the same time, the real-time signal supported by signal () is queued and will not be lost.

For the current Linux two signal installation functions: signal () and sigaction (), they can not turn sigrtmin previous signal into a reliable signal (neither queuing, still may be lost, is still unreliable signal), It also supports queuing for signals after sigrtmin. The biggest difference between these two functions is that the signals that have been installed by Sigaction can pass information to the signal processing function (which is true for all signals), and the signals that are installed by signal cannot pass information to the signal processing function. The same is true for signal-sending functions.

2, real-time signal and non-real-time signal

Early UNIX systems defined only 32 signals, and Ret hat7.2 supports 64 signals, numbering 0-63 (sigrtmin=31,sigrtmax=63), which can be further increased in the future, which needs to be supported by the kernel. The first 32 types of signals already have predefined values, each with a definite purpose and meaning, and each signal has its own default action. If you press the CTRL ^c of the keyboard, the SIGINT signal is generated, and the default response to that signal is the process termination. The latter 32 signals represent real-time signals and are equivalent to the reliable signals described earlier. This ensures that multiple real-time signals sent are received. Real-time signals are part of the POSIX standard and can be used for application processes.

Non-real-time signals do not support queueing, are unreliable signals, real-time signal support queuing, are reliable signals.

Back to top of page

Third, the process of the response to the signal

The process can respond to a signal in three ways: (1) ignore the signal, that is, no processing of the signal, wherein two signals can not be ignored: Sigkill and Sigstop, (2) capture the signal. Define the signal processing function, when the signal occurs, execute the corresponding processing function, (3) perform the default operation, Linux for each signal has a default action, for details please refer to [2] and other information. Note that the default response of a process to a real-time signal is a process termination.

Which of the three ways Linux responds to a signal depends on the parameters passed to the corresponding API function.

Back to top of page

Iv. Transmission of Signals

The main functions for 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)

value of parameter PID reception process of the signal
Pid>0 Process with process ID PID
Pid=0 Processes for the same process group
Pid<0 Pid!=-1 Process group ID for all processes with-pid
Pid=-1 All processes with process IDs greater than 1, except the sending process itself

The Sinno is a signal value that, when it is 0 o'clock (i.e. an empty signal), actually does not send any signal, but does error checking as usual, so that it can be used to check whether the target process exists and whether the current process has permission to send a signal to the target (the root-privileged process can send a signal to any process, A non-root process can only send a signal to a process that belongs to the same session or to the same user.

Kill () is most commonly used to send a signal when pid>0, the call returns 0 successfully; otherwise, 1 is returned. Note: For pid<0 situation, for which process will accept the signal, various versions of the argument, in fact, very simple, refer to the kernel source code KERNAL/SIGNAL.C, the above table rules are reference Red Hat 7.2.

2, Raise ()
#include <signal.h>
int raise (int signo)
Sends a signal to the process itself, and the parameter is the signal value that is about to be sent. The call returns 0 successfully; otherwise, 1 is returned.

3, Sigqueue ()
#include <sys/types.h>
#include <signal.h>
int Sigqueue (pid_t pid, int sig, Const Union Sigval Val)
The call returns 0 successfully; otherwise, 1 is returned.

Sigqueue () is a relatively new signaling system call, mainly for real-time signals (of course, the first 32), supporting the signal with parameters, and function sigaction () with the use.

The first parameter of the sigqueue is the process ID that specifies the receive signal, the second parameter determines the signal to be sent, and the third parameter is a federated data structure, Union Sigval, which specifies the parameters of the signal passing, that is, the 4-byte value that is commonly referred to.

typedef Union SIGVAL {int  sival_int; void *sival_ptr;} sigval_t;

Sigqueue () passes more additional information than kill (), but Sigqueue () can only send a signal to a process and not send a signal to a process group. If signo=0, an error check is performed, but no signal is actually sent, and a 0 value signal can be used to check the validity of the PID and whether the current process has permission to send a signal to the target process.

When calling Sigqueue, the information specified by sigval_t is copied to the 3 parameter signal processing function (3 parameter signal processing function refers to the signal processing function is installed by the sigaction, and set the Sa_sigaction pointer, will be elaborated later) in the siginfo_t structure, This allows the signal processing function to process this information. Because Sigqueue system calls support the sending of parametric signals, the function of the Kill () system call is much more flexible and powerful.

Note: When Sigqueue () sends a non-real-time signal, the information contained in the third parameter can still be passed to the signal processing function; when Sigqueue () sends a non-real-time signal, it still does not support queueing, that is, all the same signals that come during the execution of the signal processing function are combined into a single signal.

4, Alarm ()
#include <unistd.h>
unsigned int alarm (unsigned int seconds)
Specifically for the SIGALRM signal, after a specified time of seconds seconds, the process itself will send a SIGALRM signal, also known as the alarm time. Any previous alarm () calls will not be valid after the process calls alarm. If the parameter seconds is zero, no alarm time is included in the process.
The return value, if the alarm time has been set in the process before alarm () is called, returns the time remaining for the previous alarm time, otherwise 0.

5, Setitimer ()
#include <sys/time.h>
int Setitimer (int which, const struct itimerval *value, struct itimerval *ovalue));
Setitimer () is powerful than alarm and supports 3 types of timers:

    • Itimer_real: Set the absolute time, after the specified time, the kernel will send SIGALRM signal to the process;
    • Itimer_virtual Set the program execution time, after the specified time, the kernel will send SIGVTALRM signal to the process;
    • Itimer_prof sets the process execution and the time that the kernel consumes due to this process and, after a specified time, the kernel sends a itimer_virtual signal to the process;

Setitimer () The first parameter which specifies the timer type (one of the three above); The second parameter is an instance of the structure Itimerval, as shown in Appendix 1 in the Structure itimerval form. The third parameter is not processed.

The Setitimer () call returns 0 successfully, otherwise returns-1.

6. Abort ()
#include <stdlib.h>
void abort (void);

Sends a sigabort signal to the process, by default the process exits abnormally, and of course it can define its own signal processing function. Even if the sigabort is set to block by the process, the sigabort can still be received by the process after calling abort (). The function has no return value.

Back to top of page

Five, the signal installation (set the signal correlation action)

If a process is to process a signal, it must be installed in the process. The installation signal is used primarily to determine the mapping between the signal value and the action of the process against the signal value, i.e. which signal the process will process, and what action is taken when the signal is passed to the process.

Linux mainly has two functions for signal installation: signal (), sigaction (). where signal () is implemented on the basis of a reliable signal system invocation, it is a library function. It has only two parameters, does not support signal transmission information, mainly for the first 32 kinds of non-real-time signal installation, and sigaction () is a newer function (implemented by two system calls: Sys_signal and Sys_rt_sigaction), three parameters, support signal transmission information, Mainly used in conjunction with Sigqueue () system calls, of course, sigaction () also supports the installation of non-real-time signals. Sigaction () is better than signal () mainly reflected in the supporting signal with parameters.

1, Signal ()
#include <signal.h>
void (*signal (int signum, void (*handler))) (int));
If the function prototype is not easy to understand, you can refer to the following decomposition methods to understand:
typedef void (*sighandler_t) (int);
sighandler_t signal (int signum, sighandler_t handler));
The first parameter specifies the value of the signal, the second parameter specifies the processing of the preceding signal value, which can be ignored (the parameter is set to Sig_ign), the signal can be processed by default (the parameter is set to SIG_DFL), or it can be handled by itself (parameter specifies a function address).
If the signal () call succeeds, returns the handler value of the last Call to signal () for the installation signal Signum, and the failure to return Sig_err.

2, Sigaction ()
#include <signal.h>
int sigaction (int signum,const struct sigaction *act,struct sigaction *oldact));

The Sigaction function is used to change the behavior of a process after it receives a specific signal. The first parameter of the function is the value of the signal and can be any specific valid signal except Sigkill and sigstop (defining its own processing function for both signals, which will result in a signal installation error). The second parameter is a pointer to an instance of the struct sigaction, in the case of the struct sigaction, specifies the processing of a particular signal, which can be null, the process defaults to the signal processing, and the third parameter oldact the object to hold the original processing of the corresponding signal. Oldact can be specified as null. If the second and third parameters are set to NULL, then the function can be used to check the validity of the signal.

The second parameter is the most important, which includes the processing of the specified signal, the information transmitted by the signal, which functions should be masked during the execution of the signal processing function, and so on.

The sigaction structure is defined as follows:

struct Sigaction {          union{            __sighandler_t _sa_handler;            void (*_sa_sigaction) (int,struct siginfo *, void *);            }_u                     sigset_t sa_mask;                    unsigned long sa_flags;                   void (*sa_restorer) (void);                  }

Where, Sa_restorer, is obsolete, POSIX does not support it and should not be used again.

1. The two elements in the federated data structure _sa_handler and *_sa_sigaction specify the signal correlation function, which is the user-specified signal processing function. In addition to being a user-defined processing function, it can be either SIG_DFL (with the default processing) or sig_ign (ignoring the signal).

2, the processing function specified by _sa_handler only one parameter, that is, signal value, so the signal can not be transmitted in addition to the signal value of any information, by _sa_sigaction is the specified signal processing function with three parameters, is for the real-time signal (of course, also support non-real-time signal), It specifies a 3 parameter signal processing function. The first parameter is the signal value, the third parameter is not used (POSIX does not have the standard to use the parameter), the second parameter is a pointer to the siginfo_t structure, the structure contains the data value carried by the signal, the structure of the parameter points to the following:

siginfo_t {                  int      si_signo;  /* signal value, meaning for all signals */                  int      si_errno;  /* errno value, meaning for all signals */                  int      si_code;   /* The cause of the signal is meaningful for all signals        *          /union{/* Federated data structure, different members adapt to different signals *            ///Ensure that the allocated storage space is large enough          int _pad[si_pad_size];          A structure that is meaningful to Sigkill          struct{...              } ...            ... ...            ... ...                    For Sigill, SIGFPE, SIGSEGV, sigbus meaningful structure struct{...              } ...            ... ...            }      }

Note: In order to be easier to read, the structure is often expressed in the form shown in Appendix 2 in the description of the problem.

The federated data members in the SIGINFO_T structure ensure that the structure adapts to all signals, such as for real-time signals, in the following structural form:

typedef struct {int Si_signo;int si_errno;int si_code;union sigval si_value;} siginfo_t;

The fourth domain of a struct is also a federated data structure:

Union sigval {int sival_int;void *sival_ptr;}

Using a federated data structure, it is explained that si_value in the siginfo_t structure either holds a 4-byte integer value or holds a pointer, which constitutes the data associated with the signal. In the signal processing function, including such a signal-related data pointer, but does not specify how to operate the data, the operation method should be by the program developer according to the specific task beforehand agreement.

The third parameter of Sigqueue is the Sigval federated data structure when the system call Sigqueue is sent, and the data in that data structure is copied to the second parameter of the signal processing function when Sigqueue is called. This allows the signal to transmit some additional information at the same time as the signal is sent. Signaling can convey information to program development is very meaningful.

The transmission process of signal parameters can be illustrated as follows:

3. SA_MASK specifies which signals should be blocked during the execution of the signal processing program. By default, the current signal itself is blocked, preventing the signal from being nested, unless you specify the Sa_nodefer or Sa_nomask flag bit.

Note: Note that the Sa_mask specified signal blocking condition is the signal that is specified by the Sa_mask during the execution of the sigaction () installation signal is blocked.

4. Sa_flags contains many signs, including the Sa_nodefer and sa_nomask markers just mentioned. Another important flag bit is sa_siginfo, when the flag bit is set, the parameters that accompany the signal can be passed to the signal processing function, so you should specify the handler function for the sa_sigaction in the sigaction structure, and not for the Sa_ handler specifies the signal handler function, otherwise, setting the flag becomes meaningless. Even if the signal processing function is specified for the sa_sigaction, if the sa_siginfo is not set, the signal processing function also cannot get the data transmitted by the signal, and the access to the information in the signal processing function will result in a segment error (segmentation fault).

Note: Many references to this flag position suggest that if the flag bit is set, the three-parameter signal processing function must be defined. This is not the case, the verification method is simple: to implement a single parameter signal processing function, and in the program set the flag bit, you can see the program running results. In fact, the flag bit can be seen as a switch that signals whether the parameter is passed, if the bit is set, the parameter is passed, otherwise, the parameter is not passed.

Back to top of page

Six, signal set and signal set operation function:

A signal set is defined as a data type:

typedef struct {unsigned long sig[_nsig_words];} sigset_t

The signal set is used to describe the set of signals, and all the signals supported by Linux can appear in the signal set in whole or in part, mainly in conjunction with the signal blocking correlation function. The following are the related functions defined for the signal set operation:

#include <signal.h>int sigemptyset (sigset_t *set); int Sigfillset (sigset_t *set); int Sigaddset (sigset_t *set, int Signum) int Sigdelset (sigset_t *set, int signum), int sigismember (const sigset_t *set, int signum); Sigemptyset (sigset_t * Set) initializes the set of signals specified by the set, and all signals inside the signal set are emptied; Sigfillset (sigset_t *set) calls the function, the set points to the signal set will contain 64 kinds of signals supported by Linux; Sigaddset (sigset_t * Set, int signum) joins the Signum signal in the set-directed signal set, Sigdelset (sigset_t *set, int signum) to remove the signum signal in the set-directed signal set; Sigismember (const sigset_t *set, int signum) determines whether the signal Signum is in set-directed signal set.

Back to top of page

Seven, signal blocking and signal pending:

Each process has a set of signals to describe which signals will be blocked when they are delivered to the process, and all signals in that set will be blocked after they are delivered to the process. The following are several functions related to signal blocking:

#include <signal.h>int  sigprocmask (int how  ,  const  sigset_t *set, sigset_t *oldset)); int Sigpending (sigset_t *set)); int sigsuspend (const sigset_t *mask));

The Sigprocmask () function can operate on the signal set according to the parameter how, there are three main operations:

How
parameterprocess Current Signal set
Sig_block Adds a set of signals to the signal set in the current blocking signal set of the process
Sig_unblock If a process blocking signal set contains a signal set pointing to the signal set, the blocking of the signal is lifted
Sig_setmask Update process block signal set for set point signal set

Sigpending (sigset_t *set) obtains all signals that are currently delivered to the process but is blocked, returning the result in the set-directed signal set.

Sigsuspend (const sigset_t *mask)) is used to temporarily replace a process's signal mask with mask before receiving a signal, and pauses the process execution until the signal is received. The signal mask before the call is resumed after Sigsuspend returns. After the signal processing function is complete, the process will continue to execute. The system call always returns-1, and the errno is set to Eintr.

Appendix 1: Structure Itimerval:

            struct Itimerval {                struct timeval it_interval;/* Next value */                struct timeval it_value;    /* Current value */            };            struct Timeval {                long tv_sec;                /* seconds */                long tv_usec;               /* microseconds */            };

Appendix 2: Descriptive Description of the second parameter in a three-parameter signal processing function:

siginfo_t {int      si_signo;  /* signal value, which is meaningful for all signals */int      Si_errno;  /* errno value, meaning */int si_code for all signals      ;   /* The cause of the signal is meaningful for all signals */pid_t    si_pid;    /* The process ID to send the signal, to kill (2), real-time signal and sigchld meaningful */uid_t    si_uid;    /* Real user ID to send the signal process, for Kill (2), real-time signal and sigchld meaningful */int      si_status;/* exit status, sigchld meaningful */clock_t  si_utime;  /* User consumption time, to sigchld meaningful */clock_t  si_stime;  /* Kernel consumption of time, to sigchld meaningful */sigval_t si_value;  /* signal value, for all real-time meaningful, is a federated data structure,                          /* Can be an integer (indicated by Si_int, can also be a pointer, si_ptr marked) */void *   si_addr;   /* Trigger fault memory address, sigill,sigfpe,sigsegv,sigbus signal is meaningful */int      Si_band;   /* Meaningful */int SI_FD for sigpoll signals      ;     /* make sense for sigpoll signal */}

In fact, in addition to the first three elements, other elements are organized in a federated structure, and in the federated data structure, they are organized into different structures according to different signals. The note refers to a signal that has a meaningful meaning, in the processing function of the signal can access these fields to obtain a signal-related meaningful information, but the specific signal only interested in specific information.

Linux Signal Processing Three

Related Article

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: info-contact@alibabacloud.com 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.