The knowledge of signal signal is the foreshadowing point here
The signal is handled in three ways:
- Ignore
- Perform the default processing action for this signal
- Capturing signals
If the signal processing action is a user-defined function, call this custom function when the signal is recursive, which is called the capture signal .
The process receives a signal and is not processed immediately, but is processed at the right time! That is, before the kernel state returns to the user state!
But since the code in the signal processing function is in user space, this increases the complexity of the kernel processing signal capture.
Steps for the kernel to achieve signal capture:
- The user registers a signal processing function sighandler for a signal.
- The main program is currently executing because of a break, exception, or system call that enters the kernel state.
- Before the exception is processed to return to the main program of the user state, it is checked that the signal is not processed and that the signal needs to be handled by a user-defined function.
- The kernel decides to return to the user state to execute the Sighandler function instead of restoring the context of the main function to continue execution! (The Sighandler and main functions use different stack spaces, there are no calls and called relationships between them, and are two separate control flows)
- After the Sighandler function returns, perform a special system call Sigreturn from the user state back to the kernel state
- Check if there are any other signals that require recursion, and if not, return to the user state and resume the main program's contextual information.
Signal
A certain signal of a process (labeled Signum) registers a corresponding processing function, that is, the default processing action of the signal is modified to modify the way the handler function points;
#include <signal.h>typedef void (*sighandler_t) (int); sighandler_t signal (int signum, sighandler_t handler);
That
void (*signal (int, void (*) (int)))) (int);
The signal function accepts two parameters: an integer signal number, and a pointer to a user-defined signal handler function.
In addition, the return value of the signal function is a pointer to the calling user-defined signal handler function.
Sigaction
The Sigaction function can read and modify the processing action associated with the specified signal.
#include <signal.h>int sigaction (int signum, const struct sigaction *act, struct sigaction *oldact); struct sigactio n{ void (*sa_handler) (int); Signal processing method void (*sa_sigaction) (int, siginfo_t *, void *); The processing mode of real-time signal is not discussed sigset_t sa_mask; Extra shielded signal int sa_flags; void (*sa_restorer) (void); };
Signum is the number of the specified signal.
Processing method:
- If the act pointer is not empty, the processing action of the signal is modified according to the signal processing function in the ACT structure.
- If the oact pointer is not empty, the original processing action of the signal is transmitted through the oact.
- The original processing action is now backed up into the oact, and then the processing action of the signal is modified according to act.
(Note: the latter two parameters are input and output type parameters!) )
There are three alternative ways to Sa_handler:
- Assigning a constant sig_ign to sigaction means ignoring the signal;
- Assigning a constant SIG_DFL means performing the system default action;
- An assignment is a function pointer that captures a signal with a custom function, or registers a signal processing function with the kernel, which returns a value of void, can take an int parameter, and the number of the current signal can be learned by the parameter, so that multiple signals can be processed with the same function.
(Note: This is a callback function that is not called by the main function, but is called by the system)
When the processing function of a signal is called, the kernel automatically joins the current signal to the signal screen word of the process, and when the signal processing function returns, the original signal screen word is automatically restored, so that when a signal is processed, if the signal is generated again, it will be blocked until the current processing ends.
Pause
The pause function suspends the calling process until a signal is reached!
#include <unistd.h>int pause (void);
Processing method:
- If the signal processing action is to terminate the process, then the process terminates, the pause function has no chance to return;
- If the signal processing action is ignored, then the process continues to be suspended, and pause does not return;
- If the signal processing action is capture, then the signal handler function is called after pause returns -1,errno set to Eintr.
So pause has only the return value of the error (like the EXEC function family). The error code EINTR indicates "interrupted by signal."
Give me a chestnut.
- Define an alarm clock, after which the kernel sends a SIGALRM signal to the process;
- Call the pause function to suspend the process and the kernel to switch to another process;
- Times seconds, the kernel sends the SIGALRM signal to the process, discovers that its processing action is a custom function, and then cuts back to the user state to execute the custom handler function;
The SIGALRM signal is automatically masked when entering the SIG_ALRM function, and the SIGALRM signal is automatically unblocked when the SIG_ALRM function returns. A special system call is then performed automatically sigreturn again into the kernel, before returning to the main control flow (the MyTest function called by the main function) of the user State to continue the process.
The pause function returns 1 and then calls Alarm (0) to cancel the alarm, calling Sigaction to restore the previous processing action of the SIGALRM signal.
/************************************************************************* > File name:pause.c > Author: Lynn-zhang > Mail: [email protected] > Created time:sun 12:27:03 PM CST ************************* /#include <stdio.h> #include <signal.h> #include < Unistd.h>void sig_alarm (int signum) {printf ("I am a Custom handler!\n");} void mysleep (unsigned int times) {//Register two signal processing action struct sigaction new,old; New.sa_handler=sig_alarm; Signal processing function Sigemptyset (&new.sa_mask);//do not block any signal shielding word new.sa_flags=0; The default processing action for the SIGALRM signal is modified to custom processing action sigaction (sigalrm,&new,&old); Alarm (times); Pause (); Hang wait alarm (1); Sleep (2); Alarm (0); Cancel Alarm//restore SIGALRM signal to default processing action sigaction (sigalrm,&old,null); Alarm (1); Sleep (2);} int main () {while (1) {mysleep (2); printf ("Many seconds passed\n"); printf ("###################\n"); } return 0;}
Defines an alarm and suspends the wait, performs a custom processing action when the signal is received, and receives a SIGALRM signal to be processed by its custom handler before the default processing action is restored. Receiving a SIGALRM signal after recovering a custom processing action executes its default processing action, which terminates the process!
Capturing signals under Linux