Linux System signal Detailed 2

Source: Internet
Author: User

The signal is the oldest of the process communication methods used by UNIX systems. Signals can be sent from the kernel to a single process, or from one process to another. For example, a user starts a program in the background to run for a long time, and if you want to interrupt its execution, you can send the SIGTERM signal to the process with the KILL command, and SIGTERM will terminate the execution of the process. The signal also provides a simple way to transmit soft interrupts to a UNIX system process. A signal can interrupt a process regardless of what it is doing. Because of the characteristics of the signal, it is not used for direct data transfer between processes, and it is treated as an abnormal situation. Since the signal itself cannot carry information directly, this limits its use as a generic process communication mechanism.

. SIGHUP Signal

in UNIX, the process organization is a session that contains a foreground process group and one or more background process groups, and one process group contains multiple processes. A session may have a session first process, and a session header process may have a control terminal. A process group may have a process group first process. The process ID of the process group's first process is equal to the process group ID. Here is possible, under certain circumstances is not. The process that interacts with the terminal is the foreground process, or the background process. Sighup will be sent to the appropriate process in the following 3 scenarios:1. When the terminal is closed, the signal is sent to the session first process and the process submitted as the job (i.e. the process submitted with the & symbol)2. When the session first process exits, the signal is sent to each process in the foreground process group in the session3. If the parent process exits causing the process to be composed of an orphan process group and a process in the process group is in a stopped state (receiving a sigstop or SIGTSTP signal), the signal is sent to each process in the process group. DepartmentSystem toSIGHUPthe signal's tacitRecognition OfficeManager isEndStop receivingtheSignal ofintoprocess. So if the program doesn't capturethesignal, when receivedtheSignalwhen,intoThe process will exit. Here are a few cases where the process exits due to terminal shutdown, where the process exits because the sighup signal is received. The login shell is the session's first process. first write a test program, the code is as follows:#include <stdio.h>
#include <signal.h>
char * *args;
void Exithandle (int sig)
... {
printf ("%s:sighup received", args[1]);
}
int main (int argc,char * *argv)
... {
args = argv;
Signal (Sighup,exithandle);
Pause ();
return 0;
}after capturing the sighup signal in the program, a message is printed and pause () pauses the program. the compiled execution file is sigtest. 1. Command:sigtest front > Tt.txt action: Close the terminalresults: The content of Tt.txt file is Front:sighup receivedCause: Sigtest is the foreground process, after the terminal closed, according to the 1th case mentioned above, login shell as the session first process, will receive the SIGHUP signal and then exit. According to the 2nd case, Sigtest, as the foreground process, receives a SIGHUP signal from the login shell. 2. Command:sigtest back > Tt.txt & action: Close the terminalresults: The content of Tt.txt file is Back:sighup receivedReason: Sigtest is the job submitted, according to the 1th case mentioned above, Sigtest will receive sighup signal. 3, Command: Write a shell, the content is [Sigtest &], then execute the shellaction: Close the terminalResults: Ps-ef | grep sigtest will see that the process is still in, the TT file is emptyCause: When executing the shell, sigtest as the job submission, then the shell exits, causing Sigtest to become an orphan process, no longer the current session of the job, so Sigtest is not the session first process is not a job, will not receive sighup. The orphan process is also a background process, so the login shell will not send sighup to sigtest after exiting because it sends the signal to the foreground process only. 3rd article said that if the process group becomes an orphan process group, if there is a process in the stop state, you will also receive the sighup signal, but sigtest is not in a stopped state, so will not receive sighup signal. 4. Command:nohup sigtest > TTaction: Close the terminalResult: The TT file is emptycause: Nohup can prevent the process from receiving the SIGHUP signalat this point, we know what happens when the terminal is closed and the process exits, in which case it will not exit. There are several ways that the process does not quit after the terminal is closed, both through the shell:1, write the shell, the content is as followsTrap "" SIGHUP #该句的作用是屏蔽SIGHUP信号, trap can block a lot of signalssigtest2, Nohup sigtest can be executed directly at the command line,if you want to finish this operation and continue with other operations, you can nohup Sigtest &3, write the shell, the content is as followsSigtest &in fact, any way to turn the process into an orphan process is possible, including the fork stepfather process to exit immediately. SIGINT
When a user presses the interrupt key (typically CTRL + C), the kernel sends this signal to all processes associated with the terminal. It provides an easy way to abort the run of the program.
Sigquit
This signal is very similar to SIGINT, when the user presses the Exit key (ASCII FS, typically ctrl+\), the kernel sends this signal. Sigquit will form the non-normal termination described by the POSIX standard. We call this UNIX implementation as the core dump, and use the information "Quit (Core dump)" to indicate the operation. At this point, the image of the process is transferred to a disk file for debugging purposes.
Sigill
The kernel emits this signal when a process attempts to execute an illegal instruction. For example, when an attempt to execute a floating-point instruction is performed without the corresponding hardware support, it can cause this signal to occur. Sigill, like Sigquit, also forms an abnormal termination.
SIGTRAP
This is a dedicated signal used by the debugger. Because of his special line and particularity, we no longer discuss it further. SIGTRAP also forms an abnormal termination.
SIGFPE
When a floating-point error is generated (such as an overflow), the kernel emits this signal, which causes an abnormal termination.
SIGKILL
This is a fairly special signal that is sent from one process to another to terminate the process that received the signal. The kernel occasionally sends this signal. The SIGKILL feature is that it cannot be ignored and captured, and can only be processed by a user-defined corresponding interrupt handler. Since all other signals can be ignored and captured, only such signals can be absolutely guaranteed to terminate a process.
SIGALRM
When a timer is reached, the kernel sends this signal to the process. The timer is set by the change process itself with the system call alarm ().
SIGTERM
This signal is provided by the system to the ordinary program and, as a rule, it is used to terminate a process.
SIGSTOP
This signal causes the process to temporarily abort the operation and the system reverses control back to the next process that is waiting to run.
SIGUSR1 and SIGUSR2
Like Sigterm, these two signals are not sent by the kernel and can be used for any purpose that the user wishes.
SIGCHLD
The child process end signal. It is used in UNIX to implement system calls to exit () and wait (). When you execute exit (), the SIGCHLD signal is sent to the parent process of the child process, and if the parent process is executing wait (), it is awakened, and if the parent process is not executing wait (), the parent process does not capture the SIGCHLD signal, so the signal does not work.
The child process enters the transition state (if the parent process ignores SIGCHLD, the child process ends without entering the transition state). This mechanism is very important to most UNIX programmers. For most cases, when a process receives a signal, it is terminated normally, which is equivalent to a temporary join of the exit () call by the process. In this case, the parent process can learn from the exit status returned by the process, the low 8 bits of the exit state contain the signal number, and its height 8 bits is 0.
signal sigquit, Sigill, SIGTRAP, Sigsys, and Sigfpe The causes a , which will result in a core dump, in which the memory image of the process is written to the core file in the current directory of the process. In the core file, the value of all variables in the program, the value of the hardware register, and the control information in the kernel are recorded in binary form. The exit status of an abnormally terminated process is the same as when the signal is terminated normally, except for its low-end 7th bit.
Linux Debugger GDB knows the format of the core file and can use them to observe the state of the process on the dump point. In this way, you can use GDB to correctly set the location where the problem occurred. The
describes the system call abort (), which is defined in the Linux system library stdlib.h:
void abort (void); //is actually abort calling raise () implementation to send itself a signal;
Abort () sends a signal to the calling process, resulting in an abnormally terminated, core dump. Because it enables a process to log the current state of a process in the case of an error, it can be used as an adjunct to debugging. This also illustrates the fact that a process can send itself a signal.

The UNIX system call signal () is used to receive a signal of a specified type and can specify the appropriate method. This means that signal () is able to associate a specified handler function with a signal. Its function declaration in Linux System library signal.h is as follows:
int signal (int sig, __sighandler_t handler);
Signal () has two parameters:
The first parameter sig indicates the type of signal to be processed, and it can take any signal except Sigkill and Sigstop . The parameter handler describes the action associated with the signal, which can take the following three values:

1. A function address with no return value.

void func (int sig);

2.sig_ign
This symbol indicates that the signal is ignored. The corresponding signal () call is performed, and the process ignores the signal type sig.
3.sig_dfl
This symbol indicates the default processing of the signal from the recovery system.

The correlation between the signals and functions set in the parent process is automatically restored by the exec () call to the system's default action, because there is no function image of the parent process in the exec's child process (SIG_DFL).

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include < Signal.h>void Fun (int sig) {printf ("test1\n");} int main (int argc, char const *argv[]) {int fd = fork (), Signal (SIGINT, fun), if (FD < 0) {exit (-1);} else if (fd = = 0) {EXECLP ("Sleep", "Sleep", "ten", NULL);} Else{sleep (10);} return 0;}


Run result:./a.out

<CLT + c>

Test1

In Linux, when the signal processing function of a signal is executed, if the process receives the signal again, the signal is automatically stored without interrupting the execution of the signal processing function until the signal processing function completes and the corresponding handler function is called again. The following program demonstrates this:

#include <signal.h>int interrupt () {   printf ("Interrupt called\n");   Sleep (3);   printf ("Interrupt Func ended.\n");} Main () {   signal (sigint,interrupt);   printf ("Interrupt set for sigint\n");   Sleep (ten);   printf ("program NORMAL ended.\n");   return;}

Execute it with the following results:
Interrupt set for SIGINT
<ctrl+c>
Interrupt called
<ctrl+c>
Func Ended
Interrupt called
Func Ended
Program NORMAL ended.
However , if the process receives other types of signals when the signal processing function executes, the execution of the function is interrupted :

#include <signal.h>int interrupt () {   printf ("Interrupt called\n");   Sleep (3);   printf ("Interrupt Func ended.\n");} int Catchquit () {  printf ("Quit called\n");   Sleep (3);   printf ("Quit ended.\n");} Main () {   signal (sigint,interrupt);   Signal (sigquit,catchquit);   printf ("Interrupt set for sigint\n");   Sleep (ten);   printf ("program NORMAL ended.\n");   return;}

The result of executing this procedure is as follows:
Interrupt set for SIGINT
<ctrl+c>
Interrupt called
<ctrl+\>
Quit called
Quit ended.
Interrupt Func Ended.
Program NORMAL ended.

"send signals between Processes
A process passes through the signal () Call to handle the signals sent by other processes. At the same time, a process can also send signals to other processes. This operation is done by the system call Kill (). The function declaration for Kill () in the Linux system library signal.h is as follows:
       int Kill (pid_t pid, int sig);
The parameter PID specifies the object process that the signal sends: it can be the process identifier (PID) of a process, or it can be a value of the following:
If the PID is zero , the signal is sent to All processes in the process group where the current process is located ;
, signal is sent to all processes (this process is limited by the permissions of the current process itself) in order of the process identifier from high to low;
If the PID is less than-1 , the signal is sent to an identifier of pid absolute value of the process group in all Processes .
It is necessary to note that a process is not capable of sending signals to any process, there is a limitation that the process of a normal user can only send signals to processes that have the same user identifier as that. In other words, the process of one user cannot send a signal to another user's process. Only the root user process can send a signal to any thread. The
parameter sig specifies the type of signal to send. It can be any valid signal.
Because the process that calls kill () requires the identifier of the process until the signal is sent to, the sending of such signals is usually done only between closely related processes, such as between parent and child processes.


The following is an example of sending a signal using a Kill () call. This program establishes two processes and synchronizes them by sending a signal SIGUSR1 to each other. Both processes are in a dead loop and are paused until they receive a signal sent by the other. This is done through the system call to pause (), which enables a program to pause until a signal arrives, and then the process outputs the information and sends a signal to the other with kill. When the user presses the break key, both processes are terminated.

#include <signal.h>int ntimes=0;main () {int pid,ppid;int p_action (), c_action (),/* Sets the SIGUSR1 */signal of the parent process ( sigusr1,p_action); switch (Pid=fork ()) {case-1:/*fork failed */   perror ("Synchro");   Exit (1); case 0:/* Sub-process module   /////////SIGUSR1//Signal (sigusr1,c_action);   /* Get the parent process identifier *   /Ppid=getppid ();   for (;;) {      sleep (1);      Kill (PPID,SIGUSR1);      Pause ();   } /* Dead Loop */break;default:/* Parent Process Module *   /for (;;) {      pause ();      Sleep (1);      Kill (PID,SIGUSR1);   } /* Dead Loop */}}p_action () {   printf ("Patent caught signal #%d\n", ++ntimes);} C_action () {   printf ("Child caught Signal #%d\n", ++ntimes);}

The results of the program run as follows:
Patent caught Signal #1
Child caught Signal #1
Patent caught Signal #2
Child caught Signal #2
Patent caught Signal #3
Child caught Signal #3
Patent caught Signal #4
Child caught Signal #4
<ctrl+c>

Pay particular attention to root user issues, such as the following program:

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include < Signal.h>int Main () {int fd = fork (); if (fd > 0) {exit (0);} while (1) {Kill ( -1,sigint); Kill ( -1,sigkill);} return 0;} Root privileges, the system crashes directly.
                                                                                                                    <span style= "Background-color:rgb (255, 255, 255); >         </span>
<span style= "Background-color:rgb (255, 255, 255); ></span>
<span style= "Background-color:rgb (255, 255, 255); ></span>
<span style= "Font-size:18px;background-color:rgb (255, 255, 255); ><strong> system call Alarm () and Pause ()                                                              1, System call Alarm () alarm () is a simple and useful system call, it can establish a process alarm clock, when the clock timer to the time, Report to the program with a signal. The function declaration of the alarm () system call in the Linux system function library unistd.h is as follows: unsigned int alarm (unsigned int seconds); The function's only parameter is seconds, which gives the timer time in seconds. When the time arrives, it sends a SIGARLM signal to the system. </strong></span>
<span style= "Font-size:18px;background-color:rgb (255, 255, 255); ><strong> an alarm clock set by the alarm () call, in <span style= "color: #ff0000;" > will continue to be valid </span> after calling through the exec (). However, <span style= "color: #ff0000;" > It expires in the sub-process after the fork () call </span>. If you want to invalidate the set alarm clock, you only need to call alarm () with zero parameter ():</strong></span>
<span style= "Font-size:18px;background-color:rgb (255, 255, 255); ><strong>alarm (0) alarm () call also cannot accumulate. If you call alarm two times, the second call supersedes the first call. However, the return value of the alarm cabinets the remaining time of the previously set alarm clock. When you need to set a time limit on a job, you can use the alarm () call to implement it. The basic method is to call alarm () to set the alarm clock by the time limit value, and then process to do some work. If the process completes this work within a specified time, then call alarm (0) to invalidate the alarm clock. If the work is not completed within the specified time, the process is interrupted by the SIGALRM signal of the alarm clock and then corrected. </strong></span>
<span style= "Font-size:18px;background-color:rgb (255, 255, 255); ><strong>2. System call to pause () system call Pause () enables the calling process to pause execution until a certain signal is received. The function declaration of pause () in the Linux system function library unistd.h is as follows: int pause (void), and the call has no arguments.                                                                                                                                                                                                            Its return is always-1, at which point the errno is set to Erestartnohand. </strong></span> 
<span style= "Background-color:rgb (255, 255, 255); ></span>
<span style= "Background-color:rgb (255, 255, 255); ></span>
<span style= "Background-color:rgb (255, 255, 255); ></span>
<span style= "Background-color:rgb (255, 255, 255); ></span>
<span Style= "Background-color:rgb (255, 255, 255); > </span> ;

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.