linux--Analysis of signal processing

Source: Internet
Author: User
Tags sigint signal signal handler terminates

signal and its processing

signal processing is an event that UNIX and Linux systems generate in response to certain conditions, usually the kernel generates a signal, and the process receives a signal and takes action accordingly .

For example, when we want to force the end of a program, we usually send it a signal, then the process will catch the signal, and then the process after the execution of a certain operation is eventually terminated. Not only that, usually the following situations

  ① keyboard events (ctrl+c, ctrl+\)

② access to illegal memory

③ hardware failure ( e.g. arithmetic operation divided by 0 )

④ Environment Switch

Signals are generated , and the signals that are generated are required to be processed by the process, and the signal is also used as a way of communicating or modifying the behavior between processes, which can be explicitly sent to another process by one process. Usually when a signal is generated, we call it a signal to generate, to a signal received called signal capture . About the signal capture example is more, here are listed in the usual may often encounter several, other can self-query (~v~ although more)

Then come and meet these signals, and use    kill-l to view

The usual most common signal.

The other signals function roughly as follows (the preceding number represents the signal number),

2.ctrl + C process termination signal interrupt mode terminates process 3. CTRL + \  Exits the signal, sends a sigquit signal to all processes in the foreground process group, terminates the foreground process and generates a core file 6. Abnormal exit signal    like abort exit etc. 7. Bus and process virtual address space not successfully connected signal 8. Floating-point number anomaly error signal 9. Terminating the process signal, together with the kill command, can be used to forcibly kill a process such as the Kill-sigkill PID (note that it cannot be captured) 11-segment error signal 13. Pipe rupture Signal 14 alarm signal 17 child process return signal to parent process 19 process pause signal but it can not be captured (and 9th number Signal, more special) 20 sends a SIGTSTP signal to all processes in the foreground process group and is often used to suspend a process. Equivalent to CTRL + Z 23 processing of emergency data signals, some of the data is more urgent, can make it priority transmission. 29 Asynchronous IO Signal the 32~33 number is used for multithreading, not for the user, the signal after number 34 is unlimited, allowing us to develop our own use

For so many signals above, what is the processing of these signals?

You can see how the processing works with the man 7 signal command , the process of receiving signals is usually handled in the following 3 ways

  ① default processing mode

② Ignore

    no response to incoming signals, but SIGKILL SIGSTOP cannot be ignored)

③ Capture and process

to the incoming signal, execute our own code but note that SIGKILL and Sigtop cannot capture

Well, then look at some specific examples of signal processing

operation of the signal

(1) Registration signal

The registration signal is actually three processing of the signal, which tells the current process what to do when the signal is received.

Specifically, the signal function is used to perform the operation, which is prototyped as follows

  header file: #include <signal.h> void  (*sighandler_t)   (int  ); sighandler_t signal ( int   Signum,    sighandler_t handler);   // void (* signal (int signum, void (*handler) (int))) (int)   

Features: Begins to get a signal with a signal value of Signum, and if it gets to the signal, it starts executing the function that the handler points to (typical callback function)
return Value: the call succeeded in returning the original signal handler pointer , which failed to return Sigerr,
SIGERR's macro is #define SIG_IGN ((sighandler_t)-1)

Parameters:

   signum: Indicates the type of signal to be processed, which can take any signal except Sigkill and sigstop.

   sighandler_t: Describes the action associated with the signal, which can take the following three values, as in the table below:

Note: The above signals can be passed as the second parameter of the signal function, because they are integer but have a strong turn.

Here's an example to look at.

Like verifying the sig_ign signal so that CTRL C doesn't work  #include <stdio.h> #include <stdlib.h> #include <unistd.h> # Include <signal.h>  int main (void) {     signal (SIGINT, sig_ign);      for (int i =0; i<; ++i)     {         printf ("Don't play me! \ n ");         Sleep (1);     }     return 0; }

The results are as follows:

And look at the other

Verify the custom signal so that CTRL C executes the handler function #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h>  void Handler (int s) {      printf ("Well, I was killed.") SIGNAL =%d\n ", s);     Exit (1); }    int main (void) {      __sighandler_t ret;     RET = Signal (SIGINT, handler);          for (int i =0; i<; ++i)     {          printf ("Don't play me! \ n ");         Sleep (1);     }        

Result validation:

The above is a few simple signal processing, in fact The signal is implemented asynchronously, when the signal arrives, the system will save the current running environment of the process, go to execute signal processing function, when the signal processing function is completed, and then resume the scene, continue to execute (as if interrupt processing).

(2) Send a signal to the process

The previously mentioned signal function handles the received signal, and we can also actively send a signal to the process. There are two ways to do this, and the first one is to use the shell command

Kill-Signal Value PID

You can usually use jobs to see which background processes are in place, and if you want to run the program later, you can add the & symbol (./a.out &). At this time, if you use CTRL C again to terminate the process, you cannot succeed because CTRL + C can only be sent to the foreground process, and the end is the foreground process. at this point, you can use FG +%numid to transfer the background process to the foreground process (note: Numid is the job number, not the process PID), so ctrl C can be used. Also, you can use the Ctrl + z command If you want the foreground execution process to go back to the background and pause.

OK, and then the second way to send a signal to a process can also be through a function :

Prototype:int Kill (intint signum)

function : Use this function to send a signal value of Signum to the process ID PID process
return value :
Successful return 0, failure return-1
parameter Interpretation
signum: signal value, i.e. signal number
pid: Process ID, which can take the following four values, as in the table below: 

To mention the process group :

There are usually several processes in a process group. They can be a pipeline-connected process, which can be a parent-child process created by fork, which belongs to the same process group

To continue the application of the example ~

/*************************************************************************   > File name:3.c   > Author : TP   > Mail:    > Created time:tue 2018 08:55:26 PM CST  ****************************************** /  #include <stdio.h> #include <stdlib.h> #include <unistd.h> # Include <signal.h> void handler (int s)//Custom function, verify that you can receive the signal  {        printf ("Signal received! Recv_sig=%d\n ", s); } int main (void) {     signal (SIGUSR1, handler);     pid_t pid = fork ();     if (PID = = 0)     {         sleep (1);         Kill (Getppid (), SIGUSR1); Sends a custom signal SIGUSR1 to the parent process, which is often used to receive signaled         exit (0);     }     else     {         int i =0;         while (1)         {             printf ("%d I execute sub-process \ n", i++);             Sleep (1);  Returns >0 indicates how much time is left to allow it to be interrupted by a signal         }     }     

In addition, there are two functions to send a signal, you can see

1.Rasie (int signum);  // Send yourself a signal return value: successful return 0; failure: return-12.  Killpig (int gid,int signum)// send signal return value to process group:-  1, and set the error value to Eintr          

We can also pause the process until the process is interrupted by a signal.

The int pause (void) function is worth noting that when it pauses, it yields the CPU, unlike the while (1) loop

Classification of signals

Earlier, we enumerated so many signals, they can be broadly divided into ① reliable signal ② unreliable signal ③ real-time signal ④ non-real-time signal, so 4 kinds of signals

Unreliable signal: Signals that are numbered 1~31 are unreliable signals. because Linux signals inherit from the early UNIX signals, these unreliable signals also inherit the UNIX signal more or less defect is,

* Signal processing function is complete, the signal will be restored to the default processing (but now Liunx has improved it)

* Signal loss occurs because such signals are not queued and this situation has not been resolved for the time being

Reliable signal : SignalNo. 34-64 is a reliable signal. It will not signal loss, support queuing, signal processing function completed, will not revert to the default processing mode

real-time signal : is a reliable signal (literally feel real-time signal is faster than the non-real-time signal, it is not)

non-real-time signal: It 's an unreliable signal, actually .

(3) SIGALRM signal

This SIGALRM signal (ref. 14) is widely used in common applications. Often use the alarm function to emit a SIGALRM signal to use as alarm processing, this signal is also a useful signal, it can be used to achieve something more interesting. Of course, to use it, you have to take a look at this alarm function, which is a prototype

Features:    When the specified seconds time is up, send a SIGALRM signal return value to the current process:    success: If the process has set an alarm time before calling this alarm (), the time remaining for the previous alarm time is returned, otherwise 0 is returned. Failure returns -1 parameter explanation:00: Clear SIGALRM Signal

Apply it a little bit.

/*************************************************************************   > File name:alarm.c   > AUTHOR:TP   > Mail:    > Created time:tue 2018 09:15:53 PM CST  ************************************ /  #include <stdio.h> #include <stdlib.h> #include <unistd.h > #include <signal.h>  void handler (int s) {     printf ("\ n It's a pity that time!\n");     Exit (1); } int main (void) {     char buff[100]={};     printf ("Input string:");      Signal (SIGALRM, handler); When the SIGALRM signal is received, execute the handler function     alarm (3);   Set the 3-second alarm time, SIGALRM signal     scanf ("%s", buff) when the time is up;     Alarm (0);  Clears the alarm clock     printf ("Received:%s\n", buff);     while (1)     {         printf ("6");         Fflush (stdout);         Sleep (1);     }     return 0; }

Signal Blocking the processing action of the actual execution signal is called signal arrival , the state of the signal from generation to arrival, called signal pending. the process can choose to block a signal, and the blocked signal will remain in the pending state until the process has unblocked the signal and the subsequent arrival action is performed. Signal blocking is not the same as the signal omission described above. When the signal is blocked, it does not arrive, and the signal is ignored as an optional processing action after arrival.  at the same time, each signal has two flag bits to indicate blocking (block) and pending (Pendin) respectively. There is also a function pointer representing the processing action. When the signal is generated, the kernel sets the pending flag for the signal in the process control block until the signal arrives to eliminate the flag.if the sighup signal is not blocked or has not been generated, the default processing action is performed when it arrives. And the SIGINT signal has been generated, but is being blocked, so temporarily can not reach. Although its processing action is ignored, this signal cannot be ignored until it is unblocked because the process still has the opportunity to unblock after changing the processing action and then proceed. sigquit signal is not produced, once the resulting sigquit signal will be blocked, its processing action is user-defined function Sighandler.   If the signal is generated many times when the process is blocking a signal, LIUNX does so: the conventional signal is generated more than once before arrival, and the real-time signal generates multiple signals before it can be placed sequentially in a queue. Each signal has only one bit of the pending flag, not 0 is both 1, this place does not record how many times the signal has been generated. Similarly, the blocking flags are shown in this way . Thus, the sigset_t and blocking flags can be stored with the same data type, sigset_t, as the signal set, which can represent the "valid" or "invalid" state of each signal, "valid" and "invalid" in the blocking signal set The meaning is whether the signal is blocked and similar in the pending signal set. The block signal set is also called the current process's signal mask word. The main signal set operation function
The sigset_t type represents "valid" or "invalid" header files for each signal with a bit: #include <signal.h>①int sigemptyset (sigset_t *set);//Initializes the set of signal sets pointed to, The corresponding bit of all the signals is zeroed, indicating that the signal set does not contain any valid signals. ②int Sigfillset (sigset_t *set);//Initialize the set of signals pointed to by the set, so that the corresponding bit of all the signals in the position, A valid signal indicating the signal generator includes all signals supported by the system. ③int sigaddset (sigset_t *set,int signo);//Add some valid signal to the signal set. ④int Sigdelset (sigset_t *set,int Signo);//A valid signal is removed from the signal set ⑤int sigismemeber (const sigset_t *set,int signo);//is a Boolean function used to determine whether a signal set of the valid signal contains a certain signal, if it contains a thief returned 1, Does not contain the return 0, error returns -1⑥int sigprocmask (int how,const sigset_t *set,sigset_t *oset);//Read or change the signal mask Word of the process (blocked signal set) If successful return 0 failed to return -1⑦int Sigpending (sigset_t *set);//reads the outstanding signal set of the current process, passes through the set parameter, returns 0 when the call succeeds, and returns-1 if the error occurs.

A more classic example:

/************************************************************************* > File name:set.c > Author:tp > Mail: > Created time:thu 2018 05:38:50 PM CST ****************** /#include <stdio.h> #include <stdlib.h> #include     <unistd.h> #include <signal.h> void Printsigset (sigset_t *set) {int i = 0;         for (; i<32; i++) {if (Sigismember (set,i))//Determines whether the specified signal is Putchar (' 1 ') in the target set;     else Putchar (' 0 ');  } puts ("");}  int main () {sigset_t S, p; Define the signal Set object Sigemptyset (&s);     Empty to initialize Sigaddset (&s, SIGINT); Sigprocmask (Sig_block, &s, NULL);         Set the blocking signal set while (1) {sigpending (&p);//Get the pending signal set Printsigset (&P);     Sleep (1); } return 0; }

The general meaning of this program is that we block a signal set, keep it in a pending state, and display the signal number in it, for example, we add a CTRL + C in the middle, the signal set will appear in the back of the signal, and then they are still in a pending state.

A special reminder is that if a signal is blocked by a process, it will not be passed to the process, but will remain in the pending state, and the pending signal will be processed immediately when the process is de-processed.

linux--Analysis of signal processing

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.