The basic concept of signal
Each signal has a number and a macro definition name that can be signal.h
found in.
Use the kill -l
command to view the list of signals defined in the system: 1-31 is a normal signal; 34-64 is a live signal.
All signals are sent by the operating system!
Three ways to handle a signal
1, ignore this signal: most of the signal can be used in this way to deal with, but there are two kinds of signals must not be ignored. They are: SIGKILL
and SIGSTOP
. These two signals cannot be ignored because they provide a reliable way for the superuser to terminate or stop the process. In addition, if you omit some of the signals generated by the hardware exception (for example, illegal storage access or divided by 0), the behavior of the process is defined.
2. The default action for the signal is executed directly by the process: the system default action for most signals is to terminate the process.
3, Capture signal: perform custom actions (using signal
functions), in order to do this to inform the kernel when a signal occurs, call a user function handler
. In a user function, an executable user wants to handle this event. Note that cannot capture SIGKILL
and SIGSTOP
signal.
#include <signal.h>
typedef void (*sighandler_t) (int);
sighandler_t signal (int signum, sighandler_t handler);
signal function: registers a corresponding handler function for a particular signal of a process (labeled Signum), i.e. modifies the default processing action of the signal, modifying it to the handler
way the function points.
1, the first parameter is the marking of the signal
2, the second parameter, sighandler_t
is a typedef
come, the prototype is the void (*)(int)
function pointer, int
the parameter will be set tosignum
Take a code example:
#include <stdio.h>
#include <signal.h>
void handler (int sig)
{
printf ("Get a Sig,num Is%d\n ", SIG);
}
int main ()
{
signal (2,handler);
while (1)
{sleep
(1);
printf ("hello\n");
}
return 0;
}
The default processing action for the 2nd signal (CTRL-C) is changed to the contents of the handler
function, then when the program is run in the foreground, the default processing action (terminating the process) is not performed after you type ctrl-c
The process of signal processing:
The process receives a signal and is not processed immediately, but is handled at the right time! What is the right time? For example, when the interrupt returns, or when the kernel state returns to the user state (this situation appears more).
The signal will not necessarily be processed immediately, the operating system will not be able to process a signal to suspend the currently running process (switch process), suspend (process switching) is too much consumption, if not an emergency signal, will not be immediately processed. The operating system chooses to process the signal when the kernel state is switched back to the user state, so that it can be handled by switching between the two (without a single process switching to avoid wasting time).
is inevitable, because it is possible to receive signals in the process of sleep, the operating system is certainly unwilling to switch to the current running process, so you have to store the signal in the process of the only PCB (task_struct).
Conditions for generating signals
1. When a user presses certain keys in a terminal, the terminal driver sends a signal to the foreground program.
For example:CTRL-C generates SIGINT signals, Ctrl-\ generates SIGQUIT signals, Ctrl-z generates SIGTSTP signals
2. Hardware abnormal signal generation.
Such signals are detected by the hardware and notified to the kernel, and the kernel sends the appropriate signal to the current process.
For example: The current process executes an instruction divided by 0, and the CPU's unit of operations generates an exception, which the kernel interprets as SIGFPE signal sent to the current process.
The current process accesses an illegal memory address, and MMU produces an exception, which the kernel interprets as a SIGSEGV signal sent to the process.
3. A process invocation kill(2)
function can send a signal to another process.
You can use kill(1)
commands to send a signal to a process, the kill(1)
command is also called kill(2)
function implementation, if not explicitly specify the signal sent sigterm signal, the signal's default processing action is to terminate the process.
The generation of signals
1. The signal is generated through the terminal button
Give me a chestnut: Write a dead loop, the foreground runs this program, and then type ctrl-c in the terminal
When the CPU is executing the code of this process, the terminal driver sends a SIGINT
signal to the process, which is recorded in the PCB of the process, the user space Code of the process is suspended, and the CPU switches from user state to kernel state to process the hardware interrupt.
From the kernel state back to the user state, will first process the signal recorded in the PCB, and found that there is a signal to be SIGINT
processed, and this signal is the default processing action is to terminate the process, so directly terminate the process and no longer return its user space code execution.
2. Call the system function to signal to the process
/*************************************************************************
> File name:test.c
> Author:lynn-zhang
> Mail:iynu17@yeah.net
> Created time:fri June 2016 03:03:57 PM CST
************* /
#include <stdio.h>
int main ()
{
printf ("Get PID:%d circle ... \ n", Getpid ());
while (1);
return 0;
}
Write a program that executes a dead loop in the background, gets the ID of the process, and then sends a signal to it using the KILL command to SIGSEGV
terminate the process. You can also use the kill-11 5796,11 to be SIGSEGV
the number of the signal.
Open Terminal 1 and run the program:
Use Terminal 2 to send signals to the process
Terminal 1 shows that the process is core:
The KILL command is implemented by calling the kill function. kill函数可以给一个指定的进程发送指定信号
.
The Raise function can send a specified signal to the current process (send yourself a signal)
#include <signal.h>
int Kill (pid_t pid,int signo);
int raise (int signo);
Both of these functions return 0 successfully, and the error returns-1.
In addition, the abort
function causes the current process to receive a SIGABRT
signal and terminates abnormally.
#include <stdlib.h>
void abort (void);
Like exit
functions, functions are abort
always successful, so there is no return value.
3. Signal generated by software conditions
/*************************************************************************
> File name:alarm.c
> Author:lynn-zhang
> Mail:iynu17@yeah.net
> Created time:fri June 2016 08:52:02 PM CST
********** /
#include <stdio.h>
int main ()
{
int count=0;
Alarm (1);
while (1)
{
printf ("%d\n", count);
count++;
}
return 0;
}
By implementing the above code, the calling alarm
function can set an alarm that tells the kernel seconds
to signal the current process after seconds SIGALRM
, and the default processing action of the signal is to terminate the current process.
The program will keep counting in 1 seconds and print the counter, and 1 seconds will be signaled SIGALRM
. Because of the computer configuration and so on, each computer in a second counted the number is different generally is different.
#include <unistd.h>
unsigned int alarm (unsigned int seconds);
alarm
The return value of the function is 0 or the time remaining for the alarm clock was last set.
Blocking signal
1. Signal in the kernel of the expression:
signal Recursion Delivery: The act of actually performing signal processing signals
signal pending pending: signal from generation to arrival, signal generated but not processed
To ignore: an action after arrival
blocking BLOCK: receiving a signal does not process the blocked signal immediately will remain pending until the process has unblocked the signal to perform the arrival action
Signal generation and blocking are not directly related to arrival and unblocking is not directly related!
When a process receives a signal, it is not processed immediately, and it is processed at the right time.
Each signal is blocked and pending by two sign bits, and a function pointer represents the processing action of the signal.
In the example above,
1. SIGHUP
the signal is not blocked and has not been produced, when it reaches the default processing action.
2. SIGINT
the signal has been generated, but is being blocked, so temporarily can not reach. Although its processing action is ignored, the signal cannot be ignored until it is unblocked because the process still has the opportunity to change the processing action before unblocking it.
3. The SIGQUIT
signal has not been produced, once the SIGQUIT
signal will be blocked, its processing action is a user-defined function sighandler
. The blocking signal set is also called the signal screen Word.
The signal is generated but not processed immediately, provided it is stored in a pending
table indicating that the signal has been generated.
2. Signal Set Operation function
#include <signal.h>
int sigemptyset (sigset_t *set);//Initialize set to point to the set of signals, so that the corresponding bits of all signals 0
int Sigfillset (sigset _t *set); Initializes the set of signals that the set points to, indicating that the valid signal for the signal set includes all the signal
int sigaddset (sigset_t *set, int signo) supported by the system;//Add a valid signal int to the signal set
sigdelset (sigset_t *set, int signo); Remove the valid signal
int sigismember (const sigset_t *set, int signo) in the signal set;//To determine whether a signal is contained in a valid signal of a signal set
Parameter resolution:
sigset_t
The parameters of the structure represent the signal set, and the signal operation is operated in the form of a signal set, and the object of the structure must be created beforehand, then the signal that wants to operate is added to the Signal collection object.
Signo is the symbol of the signal.
3. Call function Sigprocmask can read or change the process's signal mask word (blocked signal set).
#include <signal.h>
int sigprocmask (int how, const sigset_t *set, sigset_t *oset);
A process's signal screen word sets the signal set that is currently blocked and cannot be delivered to the process. The calling function sigprocmask
can detect or change the signal mask word for (or both) the process. If the call sigprocmask
relieves blocking of the current number of pending signals, at least one of the sigprocmask
signals is reached before returning.
Parameter resolution:
How, there are three macros
Sig_block added to the block table
sig_unblock removed from the block table
Sig_setmask sets the block table to set the current signal mask to the value pointed to by set
set represents the newly set signal mask Word,Oset represents the current signal screen word
Treatment mode:
set non-null, oset null: Change the set point signal mask to a set of signals in the way indicated by how.
set is null,oset : Read the signal oset to the signal set, and pass oset parameters.
set and Oset are not empty: the original signal shielding word back to the oset, and then according to the set and how parameters change the signal screen Word.
4. Sigpending reads the pending signal set of the current process, passing through the set parameter
#include <signal.h>
int sigpending (sigset_t *set);
This is an output parameter that prints the table of the current process pending
to the incoming set set.
Example validates several of the above functions:
At first there is no signal, so the pending
table is full of 0, I pass CTRL + + incoming signal 2nd, see the Pending table has 2nd number is placed, after 10 seconds to cancel blocking, 2nd signal is processed (after my custom function)
Linux capture Signal
The signal is handled by three different ways:
Ignore
Perform the default processing action for this signal
Capture Signal
If the signal processing action is a user-defined function, call the custom function when the signal is reached, which is called the capture signal .
The process receives a signal and is not processed immediately, but is handled at the right time! That is, before the kernel state returns the user state !
But because the code of 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:
1, the user registers a signal processing function for a signal sighandler
.
2, is currently executing the main program, this time because of interrupts, exceptions or system calls into the kernel state.
3, before processing the exception to return to the user state of the main program, check the signal is not processed, and found that the signal needs to be processed according to user-defined functions.
4, the kernel decided to return the user state execution sighandler
function, rather than restore main
the context of the function to continue execution! ( sighandler
the main
function uses a different stack space, which does not exist between the call and the invoked relationship, and is a two separate control process).
5, sighandler
after the function returns, performs the special system call sigreturn
from the user state to the kernel state
6, check whether there are other signals need to be reached, if not then return the user state and restore the main program context information continue to execute.
Signal
Registering a corresponding processing function for a signal of a process (labeled Signum), i.e. modifying the default processing action of the signal, modifying it to the handler
way the function points;
#include <signal.h>
typedef void (*sighandler_t) (int);
sighandler_t signal (int signum, sighandler_t handler); <br>//: <br>void (*signal (int, void (*) (int))) (int) ;
The signal function accepts two parameters: an integer signal number, and a pointer to a user-defined signal processing 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);
struct sigaction
{
void (*sa_handler) (int); Signal processing mode
void (*sa_sigaction) (int, siginfo_t *, void *);//real-time signal processing mode 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.
Treatment mode:
1, if the act pointer is not empty, according to the ACT structure in the signal processing function to modify the signal processing action.
2, if the oact pointer is not empty, then through the oact outgoing signal of the original processing action.
3, now the original processing action back to the Oact, and then modify the signal according to the act of the processing action.
(Note: the latter two parameters are input-output parameters!) )
Three options will be sa_handler:
1, the assignment is a constant to SIG_IGN
sigaction
indicate ignoring the signal;
2, the assignment is constant to SIG_DFL
perform the system default action;
3, assignment is a function pointer to capture the signal with a custom function, or register a signal processing function to the kernel, the function return value is void, can take an int parameter, through the parameter can know the number of the current signal, so you can use the same function to handle a variety of signals.
(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 adds the current signal to the signal screen word of the process, and when the signal processing function returns, it automatically restores the original signal screen word, which ensures that if the signal is produced again when processing a signal, it will be blocked until the current processing is finished.
Pause
The pause function causes the calling process to hang until a signal is reached!
#include <unistd.h>
int pause (void);
Treatment mode:
If the signal processing action is to terminate the process, the process terminates and the pause
function does not have a chance to return;
If the signal processing action is ignored, the process continues to be in a suspended state and pause
does not return;
If the signal processing action is captured, then the signal processing function is invoked and pause
returned -1,errno set to Eintr.
So pause
there is only the return value of the error (similar to the EXEC function family). Error code EINTR indicates "interrupted by signal".
Give me a chestnut.
1, the definition of an alarm clock, after the appointment times seconds, the kernel to send a signal to the process SIGALRM
;
2, call the pause
function to suspend the process, the kernel switch to other processes running;
3, times seconds, the kernel sent the process SIGALRM signal, found that its processing action is a custom function, and then cut back to the user state to execute the custom processing function;
4, enter sig_alrm
the function when SIGALRM
the signal is automatically shielded from the sig_alrm
function returned when the SIGALRM
signal automatically lifted shielding. The special system call is then automatically executed sigreturn
again into the kernel, which then returns to the main control flow (function main
call function) of the user state to continue executing the process mytest
.
5, pause
function return-1, and then call the alarm(0)
cancellation alarm, call sigaction
SIGALRM
the recovery signal before the processing action.
/************************************************************************* >
File name:pause.c > Author:lynn-zhang > Mail:iynu17@yeah.net > Created time:sun Aug 2016 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 (uns
igned int times) {//Register two signal processing actions struct sigaction new,old; New.sa_handler=sig_alarm;
Signal processing function Sigemptyset (&new.sa_mask);//do not shield any signal screen word new.sa_flags=0;
The default processing action of the SIGALRM signal is modified to the custom processing action sigaction (sigalrm,&new,&old);
Alarm (times); Pause ();
Hangs up waiting 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 clock and hangs the wait, receives the signal to perform the custom processing action, before restores the default processing action, receives the SIGALRM
signal to be processed according to its custom processing function. When you receive a signal after you restore a custom processing action, SIGALRM
you perform its default processing action, which terminates the process!
Summarize
The above is on the Linux signal and capture the entire content of the signal, I hope this article on the content of everyone to learn the Linux signal can help, if there are questions welcome to discuss the message.